Using linker objects and sections
This commit is contained in:
parent
78886f11f7
commit
27d7baaac2
|
@ -1,15 +1,28 @@
|
|||
// crt.c
|
||||
#include <crt.h>
|
||||
|
||||
unsigned int CodeStart = 0x0a00;
|
||||
unsigned int StackTop = 0xa000 - 2;
|
||||
|
||||
int main(void);
|
||||
|
||||
__asm startup
|
||||
{
|
||||
lda CodeStart + 0
|
||||
byt 0x0b
|
||||
byt 0x08
|
||||
byt 0x0a
|
||||
byt 0x00
|
||||
byt 0x9e
|
||||
byt 0x32
|
||||
byt 0x30
|
||||
byt 0x36
|
||||
byt 0x31
|
||||
byt 0x00
|
||||
byt 0x00
|
||||
byt 0x00
|
||||
|
||||
lda #<bcode
|
||||
sta ip
|
||||
lda CodeStart + 1
|
||||
lda #>bcode
|
||||
sta ip + 1
|
||||
|
||||
lda StackTop + 0
|
||||
|
@ -34,6 +47,13 @@ incip:
|
|||
bcc execjmp
|
||||
inc ip + 1
|
||||
bne execjmp
|
||||
bcode:
|
||||
byt BC_LEA_ABS * 2
|
||||
byt addr
|
||||
byt <main
|
||||
byt >main
|
||||
byt BC_CALL * 2
|
||||
byt BC_EXIT * 2
|
||||
}
|
||||
|
||||
#pragma startup(startup)
|
||||
|
|
|
@ -43,7 +43,7 @@ static ByteCode TransposeBranchCondition(ByteCode code)
|
|||
}
|
||||
|
||||
ByteCodeInstruction::ByteCodeInstruction(ByteCode code)
|
||||
: mCode(code), mRelocate(false), mFunction(false), mRegisterFinal(false), mVIndex(-1), mValue(0), mRegister(0)
|
||||
: mCode(code), mRelocate(false), mRegisterFinal(false), mLinkerObject(nullptr), mValue(0), mRegister(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -199,15 +199,15 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
|||
{
|
||||
block->PutCode(generator, mCode);
|
||||
block->PutByte(mRegister);
|
||||
ByteCodeRelocation rl;
|
||||
rl.mAddr = block->mCode.Size();
|
||||
rl.mFunction = mFunction;
|
||||
rl.mLower = true;
|
||||
rl.mUpper = true;
|
||||
rl.mIndex = mVIndex;
|
||||
rl.mOffset = mValue;
|
||||
rl.mRuntime = nullptr;
|
||||
|
||||
LinkerReference rl;
|
||||
rl.mOffset = block->mCode.Size();
|
||||
rl.mLowByte = true;
|
||||
rl.mHighByte = true;
|
||||
rl.mRefObject = mLinkerObject;
|
||||
rl.mRefOffset = mValue;
|
||||
block->mRelocations.Push(rl);
|
||||
|
||||
block->PutWord(0);
|
||||
}
|
||||
else if (mValue >= 0 && mValue < 255)
|
||||
|
@ -249,14 +249,12 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
|||
block->PutCode(generator, mCode);
|
||||
if (mRelocate)
|
||||
{
|
||||
ByteCodeRelocation rl;
|
||||
rl.mAddr = block->mCode.Size();
|
||||
rl.mFunction = mFunction;
|
||||
rl.mLower = true;
|
||||
rl.mUpper = true;
|
||||
rl.mIndex = mVIndex;
|
||||
rl.mOffset = mValue;
|
||||
rl.mRuntime = nullptr;
|
||||
LinkerReference rl;
|
||||
rl.mOffset = block->mCode.Size();
|
||||
rl.mLowByte = true;
|
||||
rl.mHighByte = true;
|
||||
rl.mRefObject = mLinkerObject;
|
||||
rl.mRefOffset = mValue;
|
||||
block->mRelocations.Push(rl);
|
||||
block->PutWord(0);
|
||||
}
|
||||
|
@ -270,14 +268,12 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
|||
block->PutCode(generator, mCode); block->PutByte(mRegister);
|
||||
if (mRelocate)
|
||||
{
|
||||
ByteCodeRelocation rl;
|
||||
rl.mAddr = block->mCode.Size();
|
||||
rl.mFunction = mFunction;
|
||||
rl.mLower = true;
|
||||
rl.mUpper = true;
|
||||
rl.mIndex = mVIndex;
|
||||
rl.mOffset = mValue;
|
||||
rl.mRuntime = nullptr;
|
||||
LinkerReference rl;
|
||||
rl.mOffset = block->mCode.Size();
|
||||
rl.mLowByte = true;
|
||||
rl.mHighByte = true;
|
||||
rl.mRefObject = mLinkerObject;
|
||||
rl.mRefOffset = mValue;
|
||||
block->mRelocations.Push(rl);
|
||||
block->PutWord(0);
|
||||
}
|
||||
|
@ -435,14 +431,12 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
|||
{
|
||||
block->PutCode(generator, mCode);
|
||||
|
||||
ByteCodeRelocation rl;
|
||||
rl.mAddr = block->mCode.Size();
|
||||
rl.mFunction = mFunction;
|
||||
rl.mLower = true;
|
||||
rl.mUpper = true;
|
||||
rl.mIndex = mVIndex;
|
||||
rl.mOffset = 0;
|
||||
rl.mRuntime = nullptr;
|
||||
LinkerReference rl;
|
||||
rl.mOffset = block->mCode.Size();
|
||||
rl.mLowByte = true;
|
||||
rl.mHighByte = true;
|
||||
rl.mRefObject = mLinkerObject;
|
||||
rl.mRefOffset = 0;
|
||||
block->mRelocations.Push(rl);
|
||||
|
||||
block->PutWord(0);
|
||||
|
@ -595,10 +589,9 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr
|
|||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mIntValue;
|
||||
bins.mRelocate = true;
|
||||
bins.mFunction = false;
|
||||
mIns.Push(bins);
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
|
@ -612,7 +605,7 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr
|
|||
{
|
||||
ByteCodeInstruction bins(BC_LEA_LOCAL);
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||
bins.mValue = ins->mIntValue + proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
bins.mValue = ins->mIntValue + proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
mIns.Push(bins);
|
||||
}
|
||||
else if (ins->mMemory == IM_PARAM)
|
||||
|
@ -633,10 +626,9 @@ void ByteCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterInstr
|
|||
{
|
||||
ByteCodeInstruction bins(BC_CONST_16);
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = 0;
|
||||
bins.mRelocate = true;
|
||||
bins.mFunction = true;
|
||||
mIns.Push(bins);
|
||||
}
|
||||
}
|
||||
|
@ -686,7 +678,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
ByteCodeInstruction bins(BC_STORE_ABS_32);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[1];
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
mIns.Push(bins);
|
||||
|
@ -702,7 +694,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
int index = ins->mSIntConst[1];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -742,7 +734,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
ByteCodeInstruction bins(BC_STORE_ABS_32);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[1];
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||
mIns.Push(bins);
|
||||
|
@ -758,7 +750,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
int index = ins->mSIntConst[1];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -840,7 +832,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
ByteCodeInstruction bins(BC_STORE_ABS_16);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[1];
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
mIns.Push(bins);
|
||||
|
@ -856,7 +848,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
int index = ins->mSIntConst[1];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -893,7 +885,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
ByteCodeInstruction bins(BC_STORE_ABS_16);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[1];
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||
mIns.Push(bins);
|
||||
|
@ -910,7 +902,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
int index = ins->mSIntConst[1];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -994,7 +986,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
ByteCodeInstruction bins(BC_STORE_ABS_8);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[1];
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
mIns.Push(bins);
|
||||
|
@ -1010,7 +1002,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
int index = ins->mSIntConst[1];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -1047,7 +1039,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
ByteCodeInstruction bins(BC_STORE_ABS_16);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[1];
|
||||
bins.mRegister = BC_REG_ACCU;
|
||||
mIns.Push(bins);
|
||||
|
@ -1063,7 +1055,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
int index = ins->mSIntConst[1];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -1103,7 +1095,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
ByteCodeInstruction bins(BC_STORE_ABS_8);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[1];
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||
bins.mRegisterFinal = ins->mSFinal[0];
|
||||
|
@ -1121,7 +1113,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
int index = ins->mSIntConst[1];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -1161,7 +1153,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
ByteCodeInstruction bins(BC_STORE_ABS_16);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[1];
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]];
|
||||
bins.mRegisterFinal = ins->mSFinal[0];
|
||||
|
@ -1179,7 +1171,7 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
int index = ins->mSIntConst[1];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -1283,7 +1275,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
{
|
||||
ByteCodeInstruction bins(BC_LOAD_ABS_32);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[0];
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||
mIns.Push(bins);
|
||||
|
@ -1299,7 +1291,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
{
|
||||
int index = ins->mSIntConst[0];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -1346,7 +1338,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
{
|
||||
ByteCodeInstruction bins(BC_LOAD_ABS_16);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[0];
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||
mIns.Push(bins);
|
||||
|
@ -1362,7 +1354,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
{
|
||||
int index = ins->mSIntConst[0];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -1411,7 +1403,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
{
|
||||
ByteCodeInstruction bins((ins->mTType == IT_BOOL || ins->mTType == IT_INT8) ? BC_LOAD_ABS_8 : BC_LOAD_ABS_U8);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[0];
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||
mIns.Push(bins);
|
||||
|
@ -1427,7 +1419,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
{
|
||||
int index = ins->mSIntConst[0];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -1457,7 +1449,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
{
|
||||
ByteCodeInstruction bins(BC_LOAD_ABS_16);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[0];
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||
mIns.Push(bins);
|
||||
|
@ -1473,7 +1465,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
{
|
||||
int index = ins->mSIntConst[0];
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
|
||||
|
@ -1573,8 +1565,7 @@ void ByteCodeBasicBlock::CallFunction(InterCodeProcedure* proc, const InterInstr
|
|||
{
|
||||
ByteCodeInstruction bins(BC_LEA_ABS);
|
||||
bins.mRelocate = true;
|
||||
bins.mFunction = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = 0;
|
||||
bins.mRegister = BC_REG_ADDR;
|
||||
mIns.Push(bins);
|
||||
|
@ -1604,8 +1595,7 @@ void ByteCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInst
|
|||
{
|
||||
ByteCodeInstruction bins(BC_JSR);
|
||||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins->mVarIndex;
|
||||
bins.mFunction = ins->mMemory == IM_PROCEDURE;
|
||||
bins.mLinkerObject = ins->mLinkerObject;
|
||||
bins.mValue = ins->mSIntConst[0];
|
||||
mIns.Push(bins);
|
||||
}
|
||||
|
@ -2813,7 +2803,7 @@ ByteCodeBasicBlock* ByteCodeBasicBlock::BypassEmptyBlocks(void)
|
|||
}
|
||||
}
|
||||
|
||||
void ByteCodeBasicBlock::CopyCode(ByteCodeGenerator* generator, uint8 * target)
|
||||
void ByteCodeBasicBlock::CopyCode(ByteCodeGenerator* generator, LinkerObject* linkerObject, uint8 * target)
|
||||
{
|
||||
int i;
|
||||
int next, end;
|
||||
|
@ -2826,9 +2816,10 @@ void ByteCodeBasicBlock::CopyCode(ByteCodeGenerator* generator, uint8 * target)
|
|||
|
||||
for (int i = 0; i < mRelocations.Size(); i++)
|
||||
{
|
||||
ByteCodeRelocation rl = mRelocations[i];
|
||||
rl.mAddr += target - generator->mMemory + mOffset;
|
||||
generator->mRelocations.Push(rl);
|
||||
LinkerReference rl = mRelocations[i];
|
||||
rl.mObject = linkerObject;
|
||||
rl.mOffset += mOffset;
|
||||
generator->mLinker->AddReference(rl);
|
||||
}
|
||||
|
||||
end = mOffset + mCode.Size();
|
||||
|
@ -2869,8 +2860,8 @@ void ByteCodeBasicBlock::CopyCode(ByteCodeGenerator* generator, uint8 * target)
|
|||
mCode.Lookup(i, target[i + mOffset]);
|
||||
}
|
||||
|
||||
if (mTrueJump) mTrueJump->CopyCode(generator, target);
|
||||
if (mFalseJump) mFalseJump->CopyCode(generator, target);
|
||||
if (mTrueJump) mTrueJump->CopyCode(generator, linkerObject, target);
|
||||
if (mFalseJump) mFalseJump->CopyCode(generator, linkerObject, target);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3046,13 +3037,10 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
|
|||
|
||||
lentryBlock->CalculateOffset(total);
|
||||
|
||||
generator->AddAddress(proc->mID, true, generator->mProgEnd, total, proc->mIdent, false);
|
||||
uint8 * data = proc->mLinkerObject->AddSpace(total);
|
||||
|
||||
mProgStart = generator->mProgEnd;
|
||||
lentryBlock->CopyCode(generator, generator->mMemory + generator->mProgEnd);
|
||||
lentryBlock->CopyCode(generator, proc->mLinkerObject, data);
|
||||
mProgSize = total;
|
||||
|
||||
generator->mProgEnd += total;
|
||||
}
|
||||
|
||||
ByteCodeBasicBlock* ByteCodeProcedure::CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* sblock)
|
||||
|
@ -3067,265 +3055,19 @@ ByteCodeBasicBlock* ByteCodeProcedure::CompileBlock(InterCodeProcedure* iproc, I
|
|||
return block;
|
||||
}
|
||||
|
||||
void ByteCodeProcedure::Disassemble(FILE* file, ByteCodeGenerator* generator, InterCodeProcedure* proc)
|
||||
{
|
||||
mDisassembler.Disassemble(file, generator->mMemory, mProgStart, mProgSize, proc);
|
||||
}
|
||||
|
||||
ByteCodeGenerator::ByteCodeGenerator(void)
|
||||
: mProcedureAddr({ 0 }), mGlobalAddr({ 0 }), mRelocations({ 0 })
|
||||
ByteCodeGenerator::ByteCodeGenerator(Errors* errors, Linker* linker)
|
||||
: mErrors(errors), mLinker(linker)
|
||||
{
|
||||
mProgStart = mProgEnd = 0x0801;
|
||||
for (int i = 0; i < 128; i++)
|
||||
mByteCodeUsed[i] = false;
|
||||
|
||||
mByteCodeUsed[BC_LEA_ABS] = true;
|
||||
mByteCodeUsed[BC_CALL] = true;
|
||||
mByteCodeUsed[BC_EXIT] = true;
|
||||
mByteCodeUsed[BC_NATIVE] = true;
|
||||
}
|
||||
|
||||
ByteCodeGenerator::~ByteCodeGenerator(void)
|
||||
{
|
||||
}
|
||||
|
||||
int ByteCodeGenerator::AddGlobal(int index, const Ident* ident, int size, const uint8* data, bool assembler)
|
||||
{
|
||||
int addr = mProgEnd;
|
||||
|
||||
AddAddress(index, false, addr, size, ident, assembler);
|
||||
|
||||
if (data)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
mMemory[mProgEnd + i] = data[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
mMemory[mProgEnd + i] = 0;
|
||||
}
|
||||
|
||||
mProgEnd += size;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void ByteCodeGenerator::AddAddress(int index, bool function, int address, int size, const Ident* ident, bool assembler)
|
||||
{
|
||||
Address addr;
|
||||
addr.mIndex = index;
|
||||
addr.mFunction = function;
|
||||
addr.mAddress = address;
|
||||
addr.mSize = size;
|
||||
addr.mIdent = ident;
|
||||
addr.mAssembler = assembler;
|
||||
if (function)
|
||||
mProcedureAddr[index] = addr;
|
||||
else
|
||||
mGlobalAddr[index] = addr;
|
||||
}
|
||||
|
||||
|
||||
void ByteCodeGenerator::WriteBasicHeader(void)
|
||||
{
|
||||
mMemory[mProgEnd++] = 0x0b;
|
||||
mMemory[mProgEnd++] = 0x08;
|
||||
mMemory[mProgEnd++] = 0x0a;
|
||||
mMemory[mProgEnd++] = 0x00;
|
||||
mMemory[mProgEnd++] = 0x9e;
|
||||
mMemory[mProgEnd++] = 0x32;
|
||||
mMemory[mProgEnd++] = 0x30;
|
||||
mMemory[mProgEnd++] = 0x36;
|
||||
mMemory[mProgEnd++] = 0x31;
|
||||
mMemory[mProgEnd++] = 0x00;
|
||||
mMemory[mProgEnd++] = 0x00;
|
||||
mMemory[mProgEnd++] = 0x00;
|
||||
}
|
||||
|
||||
void ByteCodeGenerator::SetBasicEntry(int index)
|
||||
{
|
||||
mProgEntry = index;
|
||||
}
|
||||
|
||||
void ByteCodeGenerator::WriteByteCodeHeader(void)
|
||||
{
|
||||
int n = mProgEnd + 6;
|
||||
|
||||
mMemory[mProgEnd++] = BC_LEA_ABS * 2;
|
||||
mMemory[mProgEnd++] = BC_REG_ADDR;
|
||||
mMemory[mProgEnd++] = n & 255;
|
||||
mMemory[mProgEnd++] = n >> 8;
|
||||
mMemory[mProgEnd++] = BC_CALL * 2;
|
||||
mMemory[mProgEnd++] = BC_EXIT * 2;
|
||||
|
||||
mByteCodeUsed[BC_LEA_ABS] = true;
|
||||
mByteCodeUsed[BC_CALL] = true;
|
||||
mByteCodeUsed[BC_EXIT] = true;
|
||||
}
|
||||
|
||||
void ByteCodeGenerator::ResolveRelocations(void)
|
||||
{
|
||||
for (int i = 0; i < mRelocations.Size(); i++)
|
||||
{
|
||||
int dp = mRelocations[i].mAddr;
|
||||
int sp;
|
||||
if (mRelocations[i].mFunction)
|
||||
sp = mProcedureAddr[mRelocations[i].mIndex].mAddress + mRelocations[i].mOffset;
|
||||
else
|
||||
sp = mGlobalAddr[mRelocations[i].mIndex].mAddress + mRelocations[i].mOffset;
|
||||
if (mRelocations[i].mLower)
|
||||
mMemory[dp++] = sp & 255;
|
||||
if (mRelocations[i].mUpper)
|
||||
mMemory[dp++] = sp >> 8;
|
||||
}
|
||||
|
||||
int entry = mGlobalAddr[mProgEntry].mAddress;
|
||||
|
||||
mMemory[mProgStart + 5] = (entry / 1000) % 10 + '0';
|
||||
mMemory[mProgStart + 6] = (entry / 100) % 10 + '0';
|
||||
mMemory[mProgStart + 7] = (entry / 10) % 10 + '0';
|
||||
mMemory[mProgStart + 8] = entry % 10 + '0';
|
||||
}
|
||||
|
||||
bool ByteCodeGenerator::WritePRGFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
fopen_s(&file, filename, "wb");
|
||||
if (file)
|
||||
{
|
||||
mMemory[mProgStart - 2] = mProgStart & 0xff;
|
||||
mMemory[mProgStart - 1] = mProgStart >> 8;
|
||||
|
||||
int done = fwrite(mMemory + mProgStart - 2, 1, mProgEnd - mProgStart + 2, file);
|
||||
fclose(file);
|
||||
return done == mProgEnd - mProgStart + 2;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void ByteCodeGenerator::WriteAsmFile(FILE* file)
|
||||
{
|
||||
for (int i = 0; i < mGlobalAddr.Size(); i++)
|
||||
{
|
||||
WriteAsmFile(file, mGlobalAddr[i]);
|
||||
}
|
||||
for (int i = 0; i < mProcedureAddr.Size(); i++)
|
||||
{
|
||||
WriteAsmFile(file, mProcedureAddr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void ByteCodeGenerator::WriteAsmFile(FILE * file, Address & addr)
|
||||
{
|
||||
|
||||
if (addr.mAssembler)
|
||||
{
|
||||
fprintf(file, "--------------------------------------------------------------------\n");
|
||||
if (addr.mIdent)
|
||||
fprintf(file, "%s:\n", addr.mIdent->mString);
|
||||
|
||||
int ip = addr.mAddress;
|
||||
while (ip < addr.mAddress + addr.mSize)
|
||||
{
|
||||
int iip = ip;
|
||||
uint8 opcode = mMemory[ip++];
|
||||
AsmInsData d = DecInsData[opcode];
|
||||
int addr = 0;
|
||||
|
||||
switch (d.mMode)
|
||||
{
|
||||
case ASMIM_IMPLIED:
|
||||
fprintf(file, "%04x : %02x __ __ %s\n", iip, mMemory[iip], AsmInstructionNames[d.mType]);
|
||||
break;
|
||||
case ASMIM_IMMEDIATE:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s #$%02x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_ZERO_PAGE:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_ZERO_PAGE_X:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x,x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_ZERO_PAGE_Y:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x,y\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_ABSOLUTE:
|
||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||
fprintf(file, "%04x : %02x %02x %02x %s $%04x\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
|
||||
ip += 2;
|
||||
break;
|
||||
case ASMIM_ABSOLUTE_X:
|
||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||
fprintf(file, "%04x : %02x %02x %02x %s $%04x,x\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
|
||||
ip += 2;
|
||||
break;
|
||||
case ASMIM_ABSOLUTE_Y:
|
||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||
fprintf(file, "%04x : %02x %02x %02x %s $%04x,y\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
|
||||
ip += 2;
|
||||
break;
|
||||
case ASMIM_INDIRECT:
|
||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||
ip += 2;
|
||||
fprintf(file, "%04x : %02x %02x %02x %s ($%04x)\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_INDIRECT_X:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s ($%02x,x)\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_INDIRECT_Y:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s ($%02x),y\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_RELATIVE:
|
||||
addr = mMemory[ip++];
|
||||
if (addr & 0x80)
|
||||
addr = addr + ip - 256;
|
||||
else
|
||||
addr = addr + ip;
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ByteCodeGenerator::WriteMapFile(const char* filename)
|
||||
{
|
||||
FILE* file;
|
||||
fopen_s(&file, filename, "wb");
|
||||
if (file)
|
||||
{
|
||||
for (int i = 0; i < mProcedureAddr.Size(); i++)
|
||||
{
|
||||
if (mProcedureAddr[i].mIdent)
|
||||
fprintf(file, "%04x - %04x : F %s\n", mProcedureAddr[i].mAddress, mProcedureAddr[i].mAddress + mProcedureAddr[i].mSize, mProcedureAddr[i].mIdent->mString);
|
||||
else
|
||||
fprintf(file, "%04x - %04x : F\n", mProcedureAddr[i].mAddress, mProcedureAddr[i].mAddress + mProcedureAddr[i].mSize);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mGlobalAddr.Size(); i++)
|
||||
{
|
||||
if (mGlobalAddr[i].mAssembler)
|
||||
{
|
||||
if (mGlobalAddr[i].mIdent)
|
||||
fprintf(file, "%04x - %04x : A %s\n", mGlobalAddr[i].mAddress, mGlobalAddr[i].mAddress + mGlobalAddr[i].mSize, mGlobalAddr[i].mIdent->mString);
|
||||
else
|
||||
fprintf(file, "%04x - %04x : A\n", mGlobalAddr[i].mAddress, mGlobalAddr[i].mAddress + mGlobalAddr[i].mSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mGlobalAddr[i].mIdent)
|
||||
fprintf(file, "%04x - %04x : V %s\n", mGlobalAddr[i].mAddress, mGlobalAddr[i].mAddress + mGlobalAddr[i].mSize, mGlobalAddr[i].mIdent->mString);
|
||||
else
|
||||
fprintf(file, "%04x - %04x : V\n", mGlobalAddr[i].mAddress, mGlobalAddr[i].mAddress + mGlobalAddr[i].mSize);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -153,15 +153,6 @@ enum ByteCode
|
|||
class ByteCodeProcedure;
|
||||
class ByteCodeGenerator;
|
||||
|
||||
class ByteCodeRelocation
|
||||
{
|
||||
public:
|
||||
uint16 mAddr;
|
||||
bool mFunction, mLower, mUpper;
|
||||
uint16 mIndex, mOffset;
|
||||
const char * mRuntime;
|
||||
};
|
||||
|
||||
class ByteCodeBasicBlock;
|
||||
|
||||
class ByteCodeInstruction
|
||||
|
@ -173,8 +164,9 @@ public:
|
|||
|
||||
ByteCode mCode;
|
||||
uint32 mRegister;
|
||||
int mValue, mVIndex;
|
||||
bool mRelocate, mFunction, mRegisterFinal;
|
||||
int mValue;
|
||||
bool mRelocate, mRegisterFinal;
|
||||
LinkerObject* mLinkerObject;
|
||||
|
||||
bool IsStore(void) const;
|
||||
bool ChangesAccu(void) const;
|
||||
|
@ -197,7 +189,7 @@ public:
|
|||
ByteCode mBranch;
|
||||
|
||||
GrowingArray<ByteCodeInstruction> mIns;
|
||||
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||
GrowingArray<LinkerReference> mRelocations;
|
||||
|
||||
int mOffset, mSize;
|
||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled;
|
||||
|
@ -218,7 +210,7 @@ public:
|
|||
|
||||
ByteCodeBasicBlock* BypassEmptyBlocks(void);
|
||||
void CalculateOffset(int& total);
|
||||
void CopyCode(ByteCodeGenerator* generator, uint8* target);
|
||||
void CopyCode(ByteCodeGenerator* generator, LinkerObject * linkerObject, uint8* target);
|
||||
|
||||
void IntConstToAccu(__int64 val);
|
||||
void IntConstToAddr(__int64 val);
|
||||
|
@ -252,12 +244,11 @@ public:
|
|||
ByteCodeBasicBlock * entryBlock, * exitBlock;
|
||||
ByteCodeBasicBlock ** tblocks;
|
||||
|
||||
int mProgStart, mProgSize, mID;
|
||||
int mProgSize, mID;
|
||||
|
||||
void Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc);
|
||||
ByteCodeBasicBlock * CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
||||
|
||||
void Disassemble(FILE * file, ByteCodeGenerator* generator, InterCodeProcedure* proc);
|
||||
protected:
|
||||
ByteCodeDisassembler mDisassembler;
|
||||
};
|
||||
|
@ -265,39 +256,15 @@ protected:
|
|||
class ByteCodeGenerator
|
||||
{
|
||||
public:
|
||||
ByteCodeGenerator(void);
|
||||
ByteCodeGenerator(Errors* errors, Linker* linker);
|
||||
~ByteCodeGenerator(void);
|
||||
|
||||
struct Address
|
||||
{
|
||||
int mIndex, mAddress, mSize;
|
||||
bool mFunction, mAssembler;
|
||||
const Ident* mIdent;
|
||||
};
|
||||
|
||||
GrowingArray<Address> mProcedureAddr, mGlobalAddr;
|
||||
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||
Errors* mErrors;
|
||||
Linker* mLinker;
|
||||
|
||||
bool mByteCodeUsed[128];
|
||||
|
||||
uint8 mMemory[0x10000];
|
||||
int mProgEnd, mProgStart, mProgEntry;
|
||||
|
||||
void WriteBasicHeader(void);
|
||||
void WriteByteCodeHeader(void);
|
||||
void SetBasicEntry(int index);
|
||||
|
||||
bool WritePRGFile(const char* filename);
|
||||
bool WriteMapFile(const char* filename);
|
||||
|
||||
void WriteAsmFile(FILE * file);
|
||||
|
||||
void WriteAsmFile(FILE* file, Address & addr);
|
||||
|
||||
void ResolveRelocations(void);
|
||||
|
||||
int AddGlobal(int index, const Ident* ident, int size, const uint8* data, bool assembler);
|
||||
|
||||
void AddAddress(int index, bool function, int address, int size, const Ident * ident, bool assembler);
|
||||
|
||||
};
|
||||
|
|
|
@ -12,10 +12,12 @@ Compiler::Compiler(void)
|
|||
: mByteCodeFunctions(nullptr), mNativeCode(false), mDefines({nullptr, nullptr})
|
||||
{
|
||||
mErrors = new Errors();
|
||||
mLinker = new Linker(mErrors);
|
||||
mCompilationUnits = new CompilationUnits(mErrors);
|
||||
mPreprocessor = new Preprocessor(mErrors);
|
||||
mByteCodeGenerator = new ByteCodeGenerator();
|
||||
mInterCodeGenerator = new InterCodeGenerator(mErrors);
|
||||
mByteCodeGenerator = new ByteCodeGenerator(mErrors, mLinker);
|
||||
mInterCodeGenerator = new InterCodeGenerator(mErrors, mLinker);
|
||||
mNativeCodeGenerator = new NativeCodeGenerator(mErrors, mLinker);
|
||||
mInterCodeModule = new InterCodeModule();
|
||||
}
|
||||
|
||||
|
@ -61,6 +63,44 @@ bool Compiler::ParseSource(void)
|
|||
return mErrors->mErrorCount == 0;
|
||||
}
|
||||
|
||||
void Compiler::RegisterRuntime(const Location & loc, const Ident* ident)
|
||||
{
|
||||
Declaration* bcdec = mCompilationUnits->mRuntimeScope->Lookup(ident);
|
||||
if (bcdec)
|
||||
{
|
||||
LinkerObject* linkerObject = nullptr;
|
||||
int offset = 0;
|
||||
|
||||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue);
|
||||
linkerObject = bcdec->mLinkerObject;
|
||||
}
|
||||
else if (bcdec->mType == DT_LABEL)
|
||||
{
|
||||
if (!bcdec->mBase->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue);
|
||||
|
||||
linkerObject = bcdec->mBase->mLinkerObject;
|
||||
offset = bcdec->mInteger;
|
||||
}
|
||||
else if (bcdec->mType == DT_VARIABLE)
|
||||
{
|
||||
if (!bcdec->mBase->mLinkerObject)
|
||||
mInterCodeGenerator->InitGlobalVariable(mInterCodeModule, bcdec);
|
||||
linkerObject = bcdec->mLinkerObject;
|
||||
offset = bcdec->mOffset;
|
||||
}
|
||||
|
||||
mNativeCodeGenerator->RegisterRuntime(ident, linkerObject, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(loc, "Missing runtime code implementation", ident->mString);
|
||||
}
|
||||
}
|
||||
|
||||
bool Compiler::GenerateCode(void)
|
||||
{
|
||||
Location loc;
|
||||
|
@ -72,24 +112,22 @@ bool Compiler::GenerateCode(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
const Ident* sectionStartup = Ident::Unique("startup");
|
||||
const Ident* sectionBytecode = Ident::Unique("bytecode");
|
||||
const Ident* sectionCode = Ident::Unique("code");
|
||||
|
||||
mLinker->AddSection(sectionStartup, 0x0801, 0x00ff);
|
||||
mLinker->AddSection(sectionBytecode, 0x0900, 0x0100);
|
||||
mLinker->AddSection(sectionCode, 0x0a00, 0x8000);
|
||||
|
||||
dcrtstart->mSection = sectionStartup;
|
||||
|
||||
mInterCodeGenerator->mForceNativeCode = mNativeCode;
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue);
|
||||
|
||||
if (mErrors->mErrorCount != 0)
|
||||
return false;
|
||||
|
||||
mByteCodeGenerator->WriteBasicHeader();
|
||||
|
||||
mInterCodeModule->UseGlobal(dcrtstart->mVarIndex);
|
||||
|
||||
InterVariable& vmain(mInterCodeModule->mGlobalVars[dcrtstart->mVarIndex]);
|
||||
vmain.mAddr = mByteCodeGenerator->AddGlobal(vmain.mIndex, vmain.mIdent, vmain.mSize, vmain.mData, vmain.mAssembler);
|
||||
vmain.mPlaced = true;
|
||||
mByteCodeGenerator->SetBasicEntry(dcrtstart->mVarIndex);
|
||||
|
||||
mByteCodeGenerator->mProgEnd = 0x0a00;
|
||||
mByteCodeGenerator->WriteByteCodeHeader();
|
||||
|
||||
const Ident* imain = Ident::Unique("main");
|
||||
Declaration* dmain = mCompilationUnits->mScope->Lookup(imain);
|
||||
if (!dmain)
|
||||
|
@ -98,6 +136,28 @@ bool Compiler::GenerateCode(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Register native runtime functions
|
||||
|
||||
RegisterRuntime(loc, Ident::Unique("mul16by8"));
|
||||
RegisterRuntime(loc, Ident::Unique("fsplitt"));
|
||||
RegisterRuntime(loc, Ident::Unique("faddsub"));
|
||||
RegisterRuntime(loc, Ident::Unique("fmul"));
|
||||
RegisterRuntime(loc, Ident::Unique("fdiv"));
|
||||
RegisterRuntime(loc, Ident::Unique("mul16"));
|
||||
RegisterRuntime(loc, Ident::Unique("divs16"));
|
||||
RegisterRuntime(loc, Ident::Unique("mods16"));
|
||||
RegisterRuntime(loc, Ident::Unique("divu16"));
|
||||
RegisterRuntime(loc, Ident::Unique("modu16"));
|
||||
RegisterRuntime(loc, Ident::Unique("bitshift"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffloor"));
|
||||
RegisterRuntime(loc, Ident::Unique("fceil"));
|
||||
RegisterRuntime(loc, Ident::Unique("ftoi"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffromi"));
|
||||
RegisterRuntime(loc, Ident::Unique("fcmp"));
|
||||
RegisterRuntime(loc, Ident::Unique("bcexec"));
|
||||
|
||||
//
|
||||
|
||||
InterCodeProcedure* iproc = mInterCodeGenerator->TranslateProcedure(mInterCodeModule, dmain->mValue, dmain);
|
||||
|
||||
if (mErrors->mErrorCount != 0)
|
||||
|
@ -116,8 +176,8 @@ bool Compiler::GenerateCode(void)
|
|||
|
||||
if (proc->mNativeProcedure)
|
||||
{
|
||||
NativeCodeProcedure* ncproc = new NativeCodeProcedure();
|
||||
ncproc->Compile(mByteCodeGenerator, proc);
|
||||
NativeCodeProcedure* ncproc = new NativeCodeProcedure(mNativeCodeGenerator);
|
||||
ncproc->Compile(proc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -125,65 +185,13 @@ bool Compiler::GenerateCode(void)
|
|||
|
||||
bgproc->Compile(mByteCodeGenerator, proc);
|
||||
mByteCodeFunctions.Push(bgproc);
|
||||
|
||||
#if _DEBUG
|
||||
FILE* file;
|
||||
fopen_s(&file, "r:\\cldiss.txt", "a");
|
||||
|
||||
if (file)
|
||||
{
|
||||
bgproc->Disassemble(file, mByteCodeGenerator, mInterCodeModule->mProcedures[i]);
|
||||
fclose(file);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Compile used runtime functions
|
||||
|
||||
for (int i = 0; i < mByteCodeGenerator->mRelocations.Size(); i++)
|
||||
{
|
||||
if (mByteCodeGenerator->mRelocations[i].mRuntime)
|
||||
{
|
||||
Declaration* bcdec = mCompilationUnits->mRuntimeScope->Lookup(Ident::Unique(mByteCodeGenerator->mRelocations[i].mRuntime));
|
||||
if (bcdec)
|
||||
{
|
||||
int index = -1, offset = 0;
|
||||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (bcdec->mVarIndex < 0)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue);
|
||||
index = bcdec->mVarIndex;
|
||||
}
|
||||
else if (bcdec->mType == DT_LABEL)
|
||||
{
|
||||
if (bcdec->mBase->mVarIndex < 0)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue);
|
||||
index = bcdec->mBase->mVarIndex;
|
||||
offset = bcdec->mInteger;
|
||||
}
|
||||
else if (bcdec->mType == DT_VARIABLE)
|
||||
{
|
||||
if (bcdec->mBase->mVarIndex < 0)
|
||||
mInterCodeGenerator->InitGlobalVariable(mInterCodeModule, bcdec);
|
||||
index = bcdec->mVarIndex;
|
||||
offset = bcdec->mOffset + mByteCodeGenerator->mRelocations[i].mOffset;
|
||||
}
|
||||
assert(index > 0);
|
||||
mInterCodeModule->UseGlobal(index);
|
||||
|
||||
mByteCodeGenerator->mRelocations[i].mIndex = index;
|
||||
mByteCodeGenerator->mRelocations[i].mOffset = offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(loc, "Missing runtime code implementation", mByteCodeGenerator->mRelocations[i].mRuntime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compile used byte code functions
|
||||
|
||||
LinkerObject* byteCodeObject = mLinker->AddObject(loc, Ident::Unique("bytecode"), sectionBytecode, LOT_RUNTIME);
|
||||
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
if (mByteCodeGenerator->mByteCodeUsed[i])
|
||||
|
@ -191,33 +199,33 @@ bool Compiler::GenerateCode(void)
|
|||
Declaration* bcdec = mCompilationUnits->mByteCodes[i];
|
||||
if (bcdec)
|
||||
{
|
||||
int index = -1, offset = 0;
|
||||
LinkerObject* linkerObject = nullptr;
|
||||
|
||||
int offset = 0;
|
||||
if (bcdec->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (bcdec->mVarIndex < 0)
|
||||
if (!bcdec->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue);
|
||||
index = bcdec->mVarIndex;
|
||||
linkerObject = bcdec->mLinkerObject;
|
||||
}
|
||||
else if (bcdec->mType == DT_LABEL)
|
||||
{
|
||||
if (bcdec->mBase->mVarIndex < 0)
|
||||
if (!bcdec->mBase->mLinkerObject)
|
||||
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue);
|
||||
index = bcdec->mBase->mVarIndex;
|
||||
linkerObject = bcdec->mBase->mLinkerObject;
|
||||
offset = bcdec->mInteger;
|
||||
}
|
||||
|
||||
assert(index > 0);
|
||||
mInterCodeModule->UseGlobal(index);
|
||||
assert(linkerObject);
|
||||
|
||||
ByteCodeRelocation rel;
|
||||
rel.mAddr = 0x900 + 2 * i;
|
||||
rel.mFunction = false;
|
||||
rel.mLower = true;
|
||||
rel.mUpper = true;
|
||||
rel.mIndex = index;
|
||||
rel.mOffset = offset;
|
||||
rel.mRuntime = nullptr;
|
||||
mByteCodeGenerator->mRelocations.Push(rel);
|
||||
LinkerReference lref;
|
||||
lref.mObject = byteCodeObject;
|
||||
lref.mLowByte = true;
|
||||
lref.mHighByte = true;
|
||||
lref.mOffset = 2 * i;
|
||||
lref.mRefObject = linkerObject;
|
||||
lref.mRefOffset = offset;
|
||||
mLinker->AddReference(lref);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -228,33 +236,10 @@ bool Compiler::GenerateCode(void)
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mInterCodeModule->mGlobalVars.Size(); i++)
|
||||
{
|
||||
InterVariable& var(mInterCodeModule->mGlobalVars[i]);
|
||||
if (var.mUsed)
|
||||
{
|
||||
if (!var.mPlaced)
|
||||
{
|
||||
var.mAddr = mByteCodeGenerator->AddGlobal(var.mIndex, var.mIdent, var.mSize, var.mData, var.mAssembler);
|
||||
var.mPlaced = true;
|
||||
}
|
||||
for (int j = 0; j < var.mNumReferences; j++)
|
||||
{
|
||||
InterVariable::Reference& ref(var.mReferences[j]);
|
||||
ByteCodeRelocation rel;
|
||||
rel.mAddr = var.mAddr + ref.mAddr;
|
||||
rel.mFunction = ref.mFunction;
|
||||
rel.mLower = ref.mLower;
|
||||
rel.mUpper = ref.mUpper;
|
||||
rel.mIndex = ref.mIndex;
|
||||
rel.mOffset = ref.mOffset;
|
||||
rel.mRuntime = nullptr;
|
||||
mByteCodeGenerator->mRelocations.Push(rel);
|
||||
}
|
||||
}
|
||||
}
|
||||
mLinker->ReferenceObject(dcrtstart->mLinkerObject);
|
||||
mLinker->ReferenceObject(byteCodeObject);
|
||||
|
||||
mByteCodeGenerator->ResolveRelocations();
|
||||
mLinker->Link();
|
||||
|
||||
return mErrors->mErrorCount == 0;
|
||||
}
|
||||
|
@ -277,26 +262,13 @@ bool Compiler::WriteOutputFile(const char* targetPath)
|
|||
strcat_s(asmPath, "asm");
|
||||
|
||||
printf("Writing <%s>\n", prgPath);
|
||||
mByteCodeGenerator->WritePRGFile(prgPath);
|
||||
mLinker->WritePrgFile(prgPath);
|
||||
|
||||
printf("Writing <%s>\n", mapPath);
|
||||
mByteCodeGenerator->WriteMapFile(mapPath);
|
||||
mLinker->WriteMapFile(mapPath);
|
||||
|
||||
printf("Writing <%s>\n", asmPath);
|
||||
{
|
||||
FILE* file;
|
||||
fopen_s(&file, asmPath, "w");
|
||||
|
||||
if (file)
|
||||
{
|
||||
for (int i = 0; i < mByteCodeFunctions.Size(); i++)
|
||||
mByteCodeFunctions[i]->Disassemble(file, mByteCodeGenerator, mInterCodeModule->mProcedures[mByteCodeFunctions[i]->mID]);
|
||||
|
||||
mByteCodeGenerator->WriteAsmFile(file);
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
mLinker->WriteAsmFile(asmPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -307,9 +279,9 @@ int Compiler::ExecuteCode(void)
|
|||
|
||||
printf("Running emulation...\n");
|
||||
Emulator* emu = new Emulator();
|
||||
memcpy(emu->mMemory + mByteCodeGenerator->mProgStart, mByteCodeGenerator->mMemory + mByteCodeGenerator->mProgStart, mByteCodeGenerator->mProgEnd - mByteCodeGenerator->mProgStart);
|
||||
emu->mMemory[0x2d] = mByteCodeGenerator->mProgEnd & 0xff;
|
||||
emu->mMemory[0x2e] = mByteCodeGenerator->mProgEnd >> 8;
|
||||
memcpy(emu->mMemory + mLinker->mProgramStart, mLinker->mMemory + mLinker->mProgramStart, mLinker->mProgramEnd - mLinker->mProgramStart);
|
||||
emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff;
|
||||
emu->mMemory[0x2e] = mLinker->mProgramEnd >> 8;
|
||||
int ecode = emu->Emulate(2061);
|
||||
printf("Emulation result %d\n", ecode);
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
#include "CompilationUnits.h"
|
||||
#include "Preprocessor.h"
|
||||
#include "ByteCodeGenerator.h"
|
||||
#include "NativeCodeGenerator.h"
|
||||
#include "InterCodeGenerator.h"
|
||||
#include "Linker.h"
|
||||
|
||||
class Compiler
|
||||
{
|
||||
|
@ -13,9 +15,11 @@ public:
|
|||
~Compiler(void);
|
||||
|
||||
Errors* mErrors;
|
||||
Linker* mLinker;
|
||||
CompilationUnits* mCompilationUnits;
|
||||
Preprocessor* mPreprocessor;
|
||||
ByteCodeGenerator* mByteCodeGenerator;
|
||||
NativeCodeGenerator* mNativeCodeGenerator;
|
||||
InterCodeGenerator* mInterCodeGenerator;
|
||||
InterCodeModule* mInterCodeModule;
|
||||
|
||||
|
@ -38,4 +42,6 @@ public:
|
|||
|
||||
void ForceNativeCode(bool native);
|
||||
void AddDefine(const Ident* ident, const char* value);
|
||||
|
||||
void RegisterRuntime(const Location& loc, const Ident* ident);
|
||||
};
|
||||
|
|
|
@ -331,7 +331,7 @@ Expression* Expression::ConstantFold(void)
|
|||
}
|
||||
|
||||
Declaration::Declaration(const Location& loc, DecType type)
|
||||
: mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1)
|
||||
: mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr)
|
||||
{}
|
||||
|
||||
Declaration::~Declaration(void)
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "MachineTypes.h"
|
||||
#include "Assembler.h"
|
||||
|
||||
class LinkerObject;
|
||||
|
||||
enum DecType
|
||||
{
|
||||
DT_TYPE_VOID,
|
||||
|
@ -38,6 +40,7 @@ enum DecType
|
|||
DT_ANON,
|
||||
DT_LABEL,
|
||||
DT_VARIABLE_REF,
|
||||
DT_FUNCTION_REF,
|
||||
DT_LABEL_REF
|
||||
};
|
||||
|
||||
|
@ -153,8 +156,9 @@ public:
|
|||
__int64 mInteger;
|
||||
double mNumber;
|
||||
uint32 mFlags;
|
||||
const Ident * mIdent;
|
||||
const Ident * mIdent, * mSection;
|
||||
const uint8* mData;
|
||||
LinkerObject * mLinkerObject;
|
||||
|
||||
bool CanAssign(const Declaration* fromType) const;
|
||||
bool IsSame(const Declaration* dec) const;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "Disassembler.h"
|
||||
#include "ByteCodeGenerator.h"
|
||||
#include "Assembler.h"
|
||||
#include "InterCode.h"
|
||||
|
||||
ByteCodeDisassembler::ByteCodeDisassembler(void)
|
||||
{
|
||||
|
@ -36,11 +37,13 @@ const char* ByteCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodePro
|
|||
}
|
||||
}
|
||||
|
||||
void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc)
|
||||
void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident)
|
||||
{
|
||||
fprintf(file, "--------------------------------------------------------------------\n");
|
||||
if (proc->mIdent)
|
||||
if (proc && proc->mIdent)
|
||||
fprintf(file, "%s:\n", proc->mIdent->mString);
|
||||
else if (ident)
|
||||
fprintf(file, "%s:\n", ident->mString);
|
||||
|
||||
char tbuffer[10];
|
||||
#if 0
|
||||
|
@ -539,11 +542,13 @@ NativeCodeDisassembler::~NativeCodeDisassembler(void)
|
|||
|
||||
}
|
||||
|
||||
void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc)
|
||||
void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident * ident)
|
||||
{
|
||||
fprintf(file, "--------------------------------------------------------------------\n");
|
||||
if (proc->mIdent)
|
||||
if (proc && proc->mIdent)
|
||||
fprintf(file, "%s:\n", proc->mIdent->mString);
|
||||
else if (ident)
|
||||
fprintf(file, "%s:\n", ident->mString);
|
||||
|
||||
char tbuffer[10];
|
||||
|
||||
|
@ -566,15 +571,15 @@ void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int st
|
|||
break;
|
||||
case ASMIM_ZERO_PAGE:
|
||||
addr = memory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
fprintf(file, "%04x : %02x %02x __ %s %s\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
break;
|
||||
case ASMIM_ZERO_PAGE_X:
|
||||
addr = memory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x,x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
fprintf(file, "%04x : %02x %02x __ %s %s,x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
break;
|
||||
case ASMIM_ZERO_PAGE_Y:
|
||||
addr = memory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x,y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
fprintf(file, "%04x : %02x %02x __ %s %s,y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
break;
|
||||
case ASMIM_ABSOLUTE:
|
||||
addr = memory[ip] + 256 * memory[ip + 1];
|
||||
|
@ -598,11 +603,11 @@ void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int st
|
|||
break;
|
||||
case ASMIM_INDIRECT_X:
|
||||
addr = memory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s ($%02x,x)\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
fprintf(file, "%04x : %02x %02x __ %s (%s,x)\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
break;
|
||||
case ASMIM_INDIRECT_Y:
|
||||
addr = memory[ip++];
|
||||
fprintf(file, "%04x : %02x %02x __ %s ($%02x),y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
fprintf(file, "%04x : %02x %02x __ %s (%s),y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc));
|
||||
break;
|
||||
case ASMIM_RELATIVE:
|
||||
addr = memory[ip++];
|
||||
|
@ -629,6 +634,16 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP
|
|||
sprintf_s(buffer, 10, "ACCU + %d", tmp - BC_REG_ACCU);
|
||||
return buffer;
|
||||
}
|
||||
else if (tmp >= BC_REG_STACK && tmp <= BC_REG_STACK + 1)
|
||||
{
|
||||
sprintf_s(buffer, 10, "SP + %d", tmp - BC_REG_STACK);
|
||||
return buffer;
|
||||
}
|
||||
else if (tmp >= BC_REG_LOCALS && tmp <= BC_REG_LOCALS + 3)
|
||||
{
|
||||
sprintf_s(buffer, 10, "FP + %d", tmp - BC_REG_LOCALS);
|
||||
return buffer;
|
||||
}
|
||||
else if (proc && tmp >= BC_REG_TMP && tmp < BC_REG_TMP + proc->mTempSize)
|
||||
{
|
||||
int i = 0;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include "InterCode.h"
|
||||
#include "MachineTypes.h"
|
||||
#include "Ident.h"
|
||||
|
||||
class ByteCodeGenerator;
|
||||
class InterCodeProcedure;
|
||||
|
||||
class ByteCodeDisassembler
|
||||
{
|
||||
|
@ -11,7 +13,7 @@ public:
|
|||
ByteCodeDisassembler(void);
|
||||
~ByteCodeDisassembler(void);
|
||||
|
||||
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc);
|
||||
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident);
|
||||
protected:
|
||||
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc);
|
||||
};
|
||||
|
@ -22,7 +24,7 @@ public:
|
|||
NativeCodeDisassembler(void);
|
||||
~NativeCodeDisassembler(void);
|
||||
|
||||
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc);
|
||||
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident);
|
||||
protected:
|
||||
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc);
|
||||
};
|
||||
|
|
|
@ -453,7 +453,7 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
|
|||
|
||||
int Emulator::Emulate(int startIP)
|
||||
{
|
||||
int trace = 0;
|
||||
int trace = 3;
|
||||
|
||||
for (int i = 0; i < 0x10000; i++)
|
||||
mCycles[i] = 0;
|
||||
|
@ -577,7 +577,7 @@ int Emulator::Emulate(int startIP)
|
|||
break;
|
||||
}
|
||||
|
||||
if ((trace & 1) && ip == 0x0823)
|
||||
if ((trace & 1) && ip == 0x0821)
|
||||
{
|
||||
int accu = mMemory[BC_REG_ACCU] + 256 * mMemory[BC_REG_ACCU + 1];
|
||||
int ptr = mMemory[BC_REG_ADDR] + 256 * mMemory[BC_REG_ADDR + 1];
|
||||
|
|
|
@ -1010,6 +1010,7 @@ InterInstruction::InterInstruction(void)
|
|||
mVarIndex = -1;
|
||||
mIntValue = 0;
|
||||
mFloatValue = 0;
|
||||
mLinkerObject = nullptr;
|
||||
|
||||
mTTemp = INVALID_TEMPORARY;
|
||||
mSTemp[0] = INVALID_TEMPORARY;
|
||||
|
@ -1134,7 +1135,7 @@ void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, Nu
|
|||
else if (mCode == IC_STORE && mMemory == IM_LOCAL)
|
||||
{
|
||||
assert(mSTemp[1] < 0);
|
||||
if (!providedVars[mVarIndex] && (mSIntConst[1] != 0 || mOperandSize != localVars[mVarIndex].mSize))
|
||||
if (!providedVars[mVarIndex] && (mSIntConst[1] != 0 || mOperandSize != localVars[mVarIndex]->mSize))
|
||||
requiredVars += mVarIndex;
|
||||
providedVars += mVarIndex;
|
||||
}
|
||||
|
@ -1163,6 +1164,7 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
|
|||
{
|
||||
InterInstruction* ains = ctemps[mSTemp[0]];
|
||||
mSIntConst[0] = ains->mIntValue;
|
||||
mLinkerObject = ains->mLinkerObject;
|
||||
mVarIndex = ains->mVarIndex;
|
||||
mMemory = ains->mMemory;
|
||||
mSTemp[0] = -1;
|
||||
|
@ -1174,6 +1176,7 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
|
|||
{
|
||||
InterInstruction* ains = ctemps[mSTemp[1]];
|
||||
mSIntConst[1] = ains->mIntValue;
|
||||
mLinkerObject = ains->mLinkerObject;
|
||||
mVarIndex = ains->mVarIndex;
|
||||
mMemory = ains->mMemory;
|
||||
mSTemp[1] = -1;
|
||||
|
@ -1187,6 +1190,7 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte
|
|||
mCode = IC_CONSTANT;
|
||||
mIntValue = ains->mIntValue;
|
||||
mFloatValue = ains->mFloatValue;
|
||||
mLinkerObject = ains->mLinkerObject;
|
||||
mVarIndex = ains->mVarIndex;
|
||||
mMemory = ains->mMemory;
|
||||
mSTemp[0] = -1;
|
||||
|
@ -1295,11 +1299,11 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
|
|||
{
|
||||
if (mMemory == IM_LOCAL)
|
||||
{
|
||||
if (localVars[mVarIndex].mAliased)
|
||||
if (localVars[mVarIndex]->mAliased)
|
||||
;
|
||||
else if (requiredTemps[mVarIndex])
|
||||
{
|
||||
if (mSIntConst[1] == 0 && mOperandSize == localVars[mVarIndex].mSize)
|
||||
if (mSIntConst[1] == 0 && mOperandSize == localVars[mVarIndex]->mSize)
|
||||
requiredTemps -= mVarIndex;
|
||||
}
|
||||
else
|
||||
|
@ -1779,6 +1783,7 @@ static void OptimizeAddress(InterInstruction * ins, const GrowingInstructionPtrA
|
|||
if (ains->mCode == IC_CONSTANT)
|
||||
{
|
||||
ins->mSIntConst[offset] = ains->mIntValue;
|
||||
ins->mLinkerObject = ains->mLinkerObject;
|
||||
ins->mVarIndex = ains->mVarIndex;
|
||||
ins->mMemory = ains->mMemory;
|
||||
ins->mSTemp[offset] = -1;
|
||||
|
@ -1801,6 +1806,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
|
|||
if (ins->mSTemp[0] >= 0 && tvalue[ins->mSTemp[0]] && tvalue[ins->mSTemp[0]]->mCode == IC_CONSTANT)
|
||||
{
|
||||
ins->mMemory = tvalue[ins->mSTemp[0]]->mMemory;
|
||||
ins->mLinkerObject = tvalue[ins->mSTemp[0]]->mLinkerObject;
|
||||
ins->mVarIndex = tvalue[ins->mSTemp[0]]->mVarIndex;
|
||||
ins->mOperandSize = tvalue[ins->mSTemp[0]]->mOperandSize;
|
||||
ins->mSIntConst[0] = tvalue[ins->mSTemp[0]]->mIntValue;
|
||||
|
@ -1821,6 +1827,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
|
|||
case IT_POINTER:
|
||||
ins->mCode = IC_CONSTANT;
|
||||
ins->mMemory = tvalue[ins->mSTemp[0]]->mMemory;
|
||||
ins->mLinkerObject = tvalue[ins->mSTemp[0]]->mLinkerObject;
|
||||
ins->mVarIndex = tvalue[ins->mSTemp[0]]->mVarIndex;
|
||||
ins->mIntValue = tvalue[ins->mSTemp[0]]->mIntValue;
|
||||
ins->mOperandSize = tvalue[ins->mSTemp[0]]->mOperandSize;
|
||||
|
@ -1865,6 +1872,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
|
|||
ins->mCode = IC_CONSTANT;
|
||||
ins->mTType = IT_POINTER;
|
||||
ins->mMemory = tvalue[ins->mSTemp[1]]->mMemory;
|
||||
ins->mLinkerObject = tvalue[ins->mSTemp[1]]->mLinkerObject;
|
||||
ins->mVarIndex = tvalue[ins->mSTemp[1]]->mVarIndex;
|
||||
ins->mIntValue = tvalue[ins->mSTemp[1]]->mIntValue + tvalue[ins->mSTemp[0]]->mIntValue;
|
||||
ins->mOperandSize = tvalue[ins->mSTemp[1]]->mOperandSize;
|
||||
|
@ -2874,32 +2882,6 @@ void InterCodeBasicBlock::ReduceTemporaries(const GrowingIntArray& renameTable,
|
|||
}
|
||||
}
|
||||
|
||||
static void UseGlobal(GrowingVariableArray& globalVars, int index)
|
||||
{
|
||||
if (!globalVars[index].mUsed)
|
||||
{
|
||||
globalVars[index].mUsed = true;
|
||||
for (int i = 0; i < globalVars[index].mNumReferences; i++)
|
||||
{
|
||||
if (!globalVars[index].mReferences[i].mFunction)
|
||||
UseGlobal(globalVars, globalVars[index].mReferences[i].mIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeModule::UseGlobal(int index)
|
||||
{
|
||||
if (!mGlobalVars[index].mUsed)
|
||||
{
|
||||
mGlobalVars[index].mUsed = true;
|
||||
for (int i = 0; i < mGlobalVars[index].mNumReferences; i++)
|
||||
{
|
||||
if (!mGlobalVars[index].mReferences[i].mFunction)
|
||||
UseGlobal( mGlobalVars[index].mReferences[i].mIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars)
|
||||
{
|
||||
int i;
|
||||
|
@ -2921,13 +2903,9 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
|
|||
case IC_STORE:
|
||||
case IC_LOAD:
|
||||
case IC_JSR:
|
||||
if (mInstructions[i]->mMemory == IM_GLOBAL)
|
||||
if (mInstructions[i]->mMemory == IM_LOCAL)
|
||||
{
|
||||
UseGlobal(globalVars, mInstructions[i]->mVarIndex);
|
||||
}
|
||||
else if (mInstructions[i]->mMemory == IM_LOCAL)
|
||||
{
|
||||
localVars[mInstructions[i]->mVarIndex].mUsed = true;
|
||||
localVars[mInstructions[i]->mVarIndex]->mUsed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3236,10 +3214,10 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
|
|||
if (mInstructions[i]->mMemory == IM_LOCAL)
|
||||
{
|
||||
int size = mInstructions[i]->mOperandSize + mInstructions[i]->mIntValue;
|
||||
if (size > localVars[mInstructions[i]->mVarIndex].mSize)
|
||||
localVars[mInstructions[i]->mVarIndex].mSize = size;
|
||||
if (size > localVars[mInstructions[i]->mVarIndex]->mSize)
|
||||
localVars[mInstructions[i]->mVarIndex]->mSize = size;
|
||||
if (mInstructions[i]->mCode == IC_CONSTANT)
|
||||
localVars[mInstructions[i]->mVarIndex].mAliased = true;
|
||||
localVars[mInstructions[i]->mVarIndex]->mAliased = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3364,14 +3342,16 @@ void InterCodeBasicBlock::Disassemble(FILE* file, bool dumpSets)
|
|||
}
|
||||
}
|
||||
|
||||
InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & location, const Ident* ident)
|
||||
InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & location, const Ident* ident, LinkerObject * linkerObject)
|
||||
: mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1), mTempSizes(0),
|
||||
mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1),
|
||||
mValueForwardingTable(NULL), mLocalVars(InterVariable()), mModule(mod),
|
||||
mIdent(ident), mNativeProcedure(false), mLeafProcedure(false)
|
||||
mValueForwardingTable(nullptr), mLocalVars(nullptr), mModule(mod),
|
||||
mIdent(ident), mLinkerObject(linkerObject),
|
||||
mNativeProcedure(false), mLeafProcedure(false)
|
||||
{
|
||||
mID = mModule->mProcedures.Size();
|
||||
mModule->mProcedures.Push(this);
|
||||
mLinkerObject->mProc = this;
|
||||
}
|
||||
|
||||
InterCodeProcedure::~InterCodeProcedure(void)
|
||||
|
@ -3694,7 +3674,7 @@ void InterCodeProcedure::Close(void)
|
|||
for (int i = 0; i < mLocalVars.Size(); i++)
|
||||
{
|
||||
if (mLocalAliasedSet[i])
|
||||
mLocalVars[i].mAliased = true;
|
||||
mLocalVars[i]->mAliased = true;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -3805,10 +3785,10 @@ void InterCodeProcedure::MapVariables(void)
|
|||
mLocalSize = 0;
|
||||
for (int i = 0; i < mLocalVars.Size(); i++)
|
||||
{
|
||||
if (mLocalVars[i].mUsed)
|
||||
if (mLocalVars[i]->mUsed)
|
||||
{
|
||||
mLocalVars[i].mOffset = mLocalSize;
|
||||
mLocalSize += mLocalVars[i].mSize;
|
||||
mLocalVars[i]->mOffset = mLocalSize;
|
||||
mLocalSize += mLocalVars[i]->mSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3958,7 +3938,7 @@ void InterCodeProcedure::Disassemble(const char* name, bool dumpSets)
|
|||
}
|
||||
|
||||
InterCodeModule::InterCodeModule(void)
|
||||
: mGlobalVars(InterVariable()), mProcedures(nullptr)
|
||||
: mGlobalVars(nullptr), mProcedures(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <stdio.h>
|
||||
#include "MachineTypes.h"
|
||||
#include "Ident.h"
|
||||
#include "Linker.h"
|
||||
|
||||
enum InterCode
|
||||
{
|
||||
|
@ -119,7 +120,7 @@ typedef GrowingArray<InterInstruction *> GrowingInstructionArray;
|
|||
typedef GrowingArray<InterCodeProcedurePtr > GrowingInterCodeProcedurePtrArray;
|
||||
|
||||
|
||||
typedef GrowingArray<InterVariable> GrowingVariableArray;
|
||||
typedef GrowingArray<InterVariable * > GrowingVariableArray;
|
||||
|
||||
#define INVALID_TEMPORARY (-1)
|
||||
|
||||
|
@ -269,28 +270,20 @@ public:
|
|||
class InterVariable
|
||||
{
|
||||
public:
|
||||
bool mUsed, mAliased, mPlaced, mAssembler;
|
||||
int mIndex, mSize, mOffset, mAddr;
|
||||
int mNumReferences;
|
||||
const uint8 * mData;
|
||||
const Ident * mIdent;
|
||||
|
||||
struct Reference
|
||||
{
|
||||
uint16 mAddr;
|
||||
bool mFunction, mLower, mUpper;
|
||||
uint16 mIndex, mOffset;
|
||||
} *mReferences;
|
||||
Location mLocation;
|
||||
bool mUsed, mAliased;
|
||||
int mIndex, mSize, mOffset, mAddr;
|
||||
int mNumReferences;
|
||||
const Ident * mIdent;
|
||||
LinkerObject * mLinkerObject;
|
||||
|
||||
InterVariable(void)
|
||||
: mUsed(false), mAliased(false), mPlaced(false), mIndex(-1), mSize(0), mOffset(0), mNumReferences(0), mData(nullptr), mIdent(nullptr), mReferences(nullptr), mAssembler(false)
|
||||
: mUsed(false), mAliased(false), mIndex(-1), mSize(0), mOffset(0), mIdent(nullptr), mLinkerObject(nullptr)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef GrowingArray<InterVariable::Reference> GrowingInterVariableReferenceArray;
|
||||
|
||||
class InterInstruction
|
||||
{
|
||||
public:
|
||||
|
@ -307,6 +300,7 @@ public:
|
|||
__int64 mIntValue;
|
||||
double mFloatValue;
|
||||
Location mLocation;
|
||||
LinkerObject * mLinkerObject;
|
||||
|
||||
bool mInUse;
|
||||
|
||||
|
@ -497,9 +491,11 @@ public:
|
|||
GrowingVariableArray mLocalVars;
|
||||
|
||||
Location mLocation;
|
||||
const Ident * mIdent;
|
||||
const Ident * mIdent, * mSection;
|
||||
|
||||
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident);
|
||||
LinkerObject * mLinkerObject;
|
||||
|
||||
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);
|
||||
~InterCodeProcedure(void);
|
||||
|
||||
int AddTemporary(InterType type);
|
||||
|
@ -532,6 +528,4 @@ public:
|
|||
GrowingInterCodeProcedurePtrArray mProcedures;
|
||||
|
||||
GrowingVariableArray mGlobalVars;
|
||||
|
||||
void UseGlobal(int index);
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "InterCodeGenerator.h"
|
||||
#include <crtdbg.h>
|
||||
|
||||
InterCodeGenerator::InterCodeGenerator(Errors* errors)
|
||||
: mErrors(errors), mForceNativeCode(false)
|
||||
InterCodeGenerator::InterCodeGenerator(Errors* errors, Linker* linker)
|
||||
: mErrors(errors), mLinker(linker), mForceNativeCode(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -182,37 +182,30 @@ static inline InterType InterTypeOfArithmetic(InterType t1, InterType t2)
|
|||
|
||||
void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* dec)
|
||||
{
|
||||
if (dec->mVarIndex < 0)
|
||||
if (!dec->mLinkerObject)
|
||||
{
|
||||
InterVariable var;
|
||||
var.mOffset = 0;
|
||||
var.mSize = dec->mSize;
|
||||
var.mData = nullptr;
|
||||
var.mIdent = dec->mIdent;
|
||||
InterVariable * var = new InterVariable();
|
||||
var->mOffset = 0;
|
||||
var->mSize = dec->mSize;
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
|
||||
var->mIdent = dec->mIdent;
|
||||
|
||||
var->mIndex = mod->mGlobalVars.Size();
|
||||
mod->mGlobalVars.Push(var);
|
||||
|
||||
dec->mVarIndex = var->mIndex;
|
||||
dec->mLinkerObject = var->mLinkerObject;
|
||||
|
||||
uint8* d = var->mLinkerObject->AddSpace(var->mSize);
|
||||
if (dec->mValue)
|
||||
{
|
||||
if (dec->mValue->mType == EX_CONSTANT)
|
||||
{
|
||||
uint8* d = new uint8[dec->mSize];
|
||||
memset(d, 0, dec->mSize);
|
||||
var.mData = d;
|
||||
|
||||
GrowingArray<InterVariable::Reference> references({ 0 });
|
||||
BuildInitializer(mod, d, 0, dec->mValue->mDecValue, references);
|
||||
var.mNumReferences = references.Size();
|
||||
if (var.mNumReferences)
|
||||
{
|
||||
var.mReferences = new InterVariable::Reference[var.mNumReferences];
|
||||
for (int i = 0; i < var.mNumReferences; i++)
|
||||
var.mReferences[i] = references[i];
|
||||
}
|
||||
BuildInitializer(mod, d, 0, dec->mValue->mDecValue, var);
|
||||
}
|
||||
else
|
||||
mErrors->Error(dec->mLocation, "Non constant initializer");
|
||||
}
|
||||
dec->mVarIndex = mod->mGlobalVars.Size();
|
||||
var.mIndex = dec->mVarIndex;
|
||||
mod->mGlobalVars.Push(var);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,22 +219,11 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
|
|||
cexp = cexp->mRight;
|
||||
}
|
||||
|
||||
InterVariable var;
|
||||
var.mOffset = 0;
|
||||
var.mSize = osize;
|
||||
uint8* d = new uint8[osize];
|
||||
var.mData = d;
|
||||
var.mAssembler = true;
|
||||
Declaration* dec = exp->mDecValue;
|
||||
|
||||
var.mIndex = mod->mGlobalVars.Size();
|
||||
if (exp->mDecValue)
|
||||
{
|
||||
exp->mDecValue->mVarIndex = var.mIndex;
|
||||
var.mIdent = exp->mDecValue->mIdent;
|
||||
}
|
||||
mod->mGlobalVars.Push(var);
|
||||
dec->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_NATIVE_CODE);
|
||||
|
||||
GrowingArray<InterVariable::Reference> references({ 0 });
|
||||
uint8* d = dec->mLinkerObject->AddSpace(osize);
|
||||
|
||||
cexp = exp;
|
||||
while (cexp)
|
||||
|
@ -265,18 +247,36 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
|
|||
d[offset++] = cexp->mLeft->mDecValue->mInteger & 255;
|
||||
else if (aexp->mType == DT_LABEL_REF)
|
||||
{
|
||||
if (aexp->mBase->mBase->mVarIndex < 0)
|
||||
if (!aexp->mBase->mBase->mLinkerObject)
|
||||
TranslateAssembler(mod, aexp->mBase->mBase->mValue);
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = aexp->mFlags & DTF_UPPER_BYTE;
|
||||
ref.mLower = !(aexp->mFlags & DTF_UPPER_BYTE);
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mBase->mBase->mVarIndex;
|
||||
ref.mOffset = aexp->mOffset + aexp->mBase->mInteger;
|
||||
LinkerReference ref;
|
||||
ref.mObject = dec->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = aexp->mFlags & DTF_UPPER_BYTE;
|
||||
ref.mLowByte = !(aexp->mFlags & DTF_UPPER_BYTE);
|
||||
ref.mRefObject = aexp->mBase->mBase->mLinkerObject;
|
||||
ref.mRefOffset = aexp->mOffset + aexp->mBase->mInteger;
|
||||
mLinker->AddReference(ref);
|
||||
|
||||
references.Push(ref);
|
||||
offset += 1;
|
||||
}
|
||||
else if (aexp->mType == DT_FUNCTION_REF)
|
||||
{
|
||||
if (!aexp->mBase->mLinkerObject)
|
||||
{
|
||||
InterCodeProcedure* cproc = this->TranslateProcedure(mod, aexp->mBase->mValue, aexp->mBase);
|
||||
cproc->ReduceTemporaries();
|
||||
}
|
||||
|
||||
LinkerReference ref;
|
||||
ref.mObject = dec->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = aexp->mFlags & DTF_UPPER_BYTE;
|
||||
ref.mLowByte = !(aexp->mFlags & DTF_UPPER_BYTE);
|
||||
ref.mRefObject = aexp->mBase->mLinkerObject;
|
||||
ref.mRefOffset = aexp->mOffset;
|
||||
mLinker->AddReference(ref);
|
||||
|
||||
offset += 1;
|
||||
}
|
||||
|
@ -298,52 +298,49 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
|
|||
}
|
||||
else if (aexp->mType == DT_LABEL)
|
||||
{
|
||||
if (aexp->mBase->mVarIndex < 0)
|
||||
if (!aexp->mBase->mLinkerObject)
|
||||
TranslateAssembler(mod, aexp->mBase->mValue);
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mBase->mVarIndex;
|
||||
ref.mOffset = aexp->mInteger;
|
||||
|
||||
references.Push(ref);
|
||||
LinkerReference ref;
|
||||
ref.mObject = dec->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
ref.mRefObject = aexp->mBase->mLinkerObject;
|
||||
ref.mRefOffset = aexp->mInteger;
|
||||
mLinker->AddReference(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
else if (aexp->mType == DT_LABEL_REF)
|
||||
{
|
||||
if (aexp->mBase->mBase->mVarIndex < 0)
|
||||
if (!aexp->mBase->mBase->mLinkerObject)
|
||||
TranslateAssembler(mod, aexp->mBase->mBase->mValue);
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mBase->mBase->mVarIndex;
|
||||
ref.mOffset = aexp->mOffset + aexp->mBase->mInteger;
|
||||
|
||||
references.Push(ref);
|
||||
LinkerReference ref;
|
||||
ref.mObject = dec->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
ref.mRefObject = aexp->mBase->mBase->mLinkerObject;
|
||||
ref.mRefOffset = aexp->mOffset + aexp->mBase->mInteger;
|
||||
mLinker->AddReference(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
else if (aexp->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (aexp->mVarIndex < 0)
|
||||
if (!aexp->mLinkerObject)
|
||||
TranslateAssembler(mod, aexp->mValue);
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mVarIndex;
|
||||
ref.mOffset = 0;
|
||||
|
||||
references.Push(ref);
|
||||
LinkerReference ref;
|
||||
ref.mObject = dec->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
ref.mRefObject = aexp->mLinkerObject;
|
||||
ref.mRefOffset = 0;
|
||||
mLinker->AddReference(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
|
@ -353,15 +350,14 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
|
|||
{
|
||||
InitGlobalVariable(mod, aexp);
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mVarIndex;
|
||||
ref.mOffset = 0;
|
||||
|
||||
references.Push(ref);
|
||||
LinkerReference ref;
|
||||
ref.mObject = dec->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
ref.mRefObject = aexp->mLinkerObject;
|
||||
ref.mRefOffset = 0;
|
||||
mLinker->AddReference(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
|
@ -372,19 +368,56 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
|
|||
{
|
||||
InitGlobalVariable(mod, aexp->mBase);
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mBase->mVarIndex;
|
||||
ref.mOffset = aexp->mOffset;
|
||||
|
||||
references.Push(ref);
|
||||
LinkerReference ref;
|
||||
ref.mObject = dec->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
ref.mRefObject = aexp->mBase->mLinkerObject;
|
||||
ref.mRefOffset = aexp->mOffset;
|
||||
mLinker->AddReference(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
}
|
||||
else if (aexp->mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
if (!aexp->mLinkerObject)
|
||||
{
|
||||
InterCodeProcedure* cproc = this->TranslateProcedure(mod, aexp->mValue, aexp);
|
||||
cproc->ReduceTemporaries();
|
||||
}
|
||||
|
||||
LinkerReference ref;
|
||||
ref.mObject = dec->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
ref.mRefObject = aexp->mLinkerObject;
|
||||
ref.mRefOffset = 0;
|
||||
mLinker->AddReference(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
else if (aexp->mType == DT_FUNCTION_REF)
|
||||
{
|
||||
if (!aexp->mBase->mLinkerObject)
|
||||
{
|
||||
InterCodeProcedure* cproc = this->TranslateProcedure(mod, aexp->mBase->mValue, aexp->mBase);
|
||||
cproc->ReduceTemporaries();
|
||||
}
|
||||
|
||||
LinkerReference ref;
|
||||
ref.mObject = dec->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
ref.mRefObject = aexp->mBase->mLinkerObject;
|
||||
ref.mRefOffset = aexp->mOffset;
|
||||
mLinker->AddReference(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
break;
|
||||
case ASMIM_RELATIVE:
|
||||
d[offset] = aexp->mInteger - offset - 1;
|
||||
|
@ -396,16 +429,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
|
|||
}
|
||||
|
||||
assert(offset == osize);
|
||||
|
||||
InterVariable& ivar(mod->mGlobalVars[var.mIndex]);
|
||||
|
||||
ivar.mNumReferences = references.Size();
|
||||
if (ivar.mNumReferences)
|
||||
{
|
||||
ivar.mReferences = new InterVariable::Reference[ivar.mNumReferences];
|
||||
for (int i = 0; i < ivar.mNumReferences; i++)
|
||||
ivar.mReferences[i] = references[i];
|
||||
}
|
||||
}
|
||||
|
||||
InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock)
|
||||
|
@ -500,7 +523,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
case DT_CONST_FUNCTION:
|
||||
{
|
||||
if (dec->mVarIndex < 0)
|
||||
if (!dec->mLinkerObject)
|
||||
{
|
||||
InterCodeProcedure* cproc = this->TranslateProcedure(proc->mModule, dec->mValue, dec);
|
||||
cproc->ReduceTemporaries();
|
||||
|
@ -511,6 +534,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mTType = InterTypeOf(dec->mBase);
|
||||
ins->mTTemp = proc->AddTemporary(ins->mTType);
|
||||
ins->mVarIndex = dec->mVarIndex;
|
||||
ins->mLinkerObject = dec->mLinkerObject;
|
||||
ins->mMemory = IM_PROCEDURE;
|
||||
ins->mIntValue = 0;
|
||||
block->Append(ins);
|
||||
|
@ -525,15 +549,17 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
case DT_CONST_DATA:
|
||||
{
|
||||
if (dec->mVarIndex < 0)
|
||||
if (!dec->mLinkerObject)
|
||||
{
|
||||
dec->mVarIndex = proc->mModule->mGlobalVars.Size();
|
||||
InterVariable var;
|
||||
var.mIndex = dec->mVarIndex;
|
||||
var.mIdent = dec->mIdent;
|
||||
var.mOffset = 0;
|
||||
var.mSize = dec->mSize;
|
||||
var.mData = dec->mData;
|
||||
InterVariable* var = new InterVariable();
|
||||
var->mIndex = dec->mVarIndex;
|
||||
var->mIdent = dec->mIdent;
|
||||
var->mOffset = 0;
|
||||
var->mSize = dec->mSize;
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
|
||||
dec->mLinkerObject = var->mLinkerObject;
|
||||
var->mLinkerObject->AddData(dec->mData, dec->mSize);
|
||||
proc->mModule->mGlobalVars.Push(var);
|
||||
}
|
||||
|
||||
|
@ -543,6 +569,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mTTemp = proc->AddTemporary(IT_POINTER);
|
||||
ins->mIntValue = 0;
|
||||
ins->mVarIndex = dec->mVarIndex;
|
||||
ins->mLinkerObject = dec->mLinkerObject;
|
||||
ins->mMemory = IM_GLOBAL;
|
||||
block->Append(ins);
|
||||
return ExValue(dec->mBase, ins->mTTemp, 1);
|
||||
|
@ -550,31 +577,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
case DT_CONST_STRUCT:
|
||||
{
|
||||
if (dec->mVarIndex < 0)
|
||||
if (!dec->mLinkerObject)
|
||||
{
|
||||
InterVariable var;
|
||||
var.mOffset = 0;
|
||||
var.mSize = dec->mSize;
|
||||
var.mData = nullptr;
|
||||
var.mIdent = dec->mIdent;
|
||||
|
||||
uint8* d = new uint8[dec->mSize];
|
||||
memset(d, 0, dec->mSize);
|
||||
var.mData = d;
|
||||
|
||||
GrowingArray<InterVariable::Reference> references({ 0 });
|
||||
BuildInitializer(proc->mModule, d, 0, dec, references);
|
||||
var.mNumReferences = references.Size();
|
||||
if (var.mNumReferences)
|
||||
{
|
||||
var.mReferences = new InterVariable::Reference[var.mNumReferences];
|
||||
for (int i = 0; i < var.mNumReferences; i++)
|
||||
var.mReferences[i] = references[i];
|
||||
}
|
||||
|
||||
InterVariable * var = new InterVariable();
|
||||
var->mOffset = 0;
|
||||
var->mSize = dec->mSize;
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
|
||||
dec->mLinkerObject = var->mLinkerObject;
|
||||
var->mIdent = dec->mIdent;
|
||||
dec->mVarIndex = proc->mModule->mGlobalVars.Size();
|
||||
var.mIndex = dec->mVarIndex;
|
||||
var->mIndex = dec->mVarIndex;
|
||||
proc->mModule->mGlobalVars.Push(var);
|
||||
|
||||
uint8* d = var->mLinkerObject->AddSpace(dec->mSize);;
|
||||
|
||||
BuildInitializer(proc->mModule, d, 0, dec, var);
|
||||
}
|
||||
|
||||
InterInstruction * ins = new InterInstruction();
|
||||
|
@ -583,6 +600,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins->mTTemp = proc->AddTemporary(IT_POINTER);
|
||||
ins->mIntValue = 0;
|
||||
ins->mVarIndex = dec->mVarIndex;
|
||||
ins->mLinkerObject = dec->mLinkerObject;
|
||||
ins->mMemory = IM_GLOBAL;
|
||||
block->Append(ins);
|
||||
return ExValue(dec->mBase, ins->mTTemp, 1);
|
||||
|
@ -610,6 +628,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
{
|
||||
InitGlobalVariable(proc->mModule, dec);
|
||||
ins->mMemory = IM_GLOBAL;
|
||||
ins->mLinkerObject = dec->mLinkerObject;
|
||||
}
|
||||
else
|
||||
ins->mMemory = IM_LOCAL;
|
||||
|
@ -1531,202 +1550,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
case EX_ASSEMBLER:
|
||||
{
|
||||
int offset = 0, osize = 0;
|
||||
Expression* cexp = exp;
|
||||
while (cexp)
|
||||
{
|
||||
osize += AsmInsSize(cexp->mAsmInsType, cexp->mAsmInsMode);
|
||||
cexp = cexp->mRight;
|
||||
}
|
||||
TranslateAssembler(proc->mModule, exp);
|
||||
|
||||
InterInstruction * ins = new InterInstruction();
|
||||
ins->mCode = IC_CONSTANT;
|
||||
ins->mTType = IT_POINTER;
|
||||
ins->mTTemp = proc->AddTemporary(ins->mTType);
|
||||
ins->mOperandSize = osize;
|
||||
ins->mIntValue = 0;
|
||||
|
||||
InterVariable var;
|
||||
var.mOffset = 0;
|
||||
var.mSize = osize;
|
||||
uint8* d = new uint8[osize];
|
||||
var.mData = d;
|
||||
var.mAssembler = true;
|
||||
|
||||
|
||||
var.mIndex = proc->mModule->mGlobalVars.Size();
|
||||
if (exp->mDecValue)
|
||||
{
|
||||
exp->mDecValue->mVarIndex = var.mIndex;
|
||||
var.mIdent = exp->mDecValue->mIdent;
|
||||
}
|
||||
proc->mModule->mGlobalVars.Push(var);
|
||||
|
||||
GrowingArray<InterVariable::Reference> references({ 0 });
|
||||
|
||||
cexp = exp;
|
||||
while (cexp)
|
||||
{
|
||||
if (cexp->mAsmInsType != ASMIT_BYTE)
|
||||
{
|
||||
int opcode = AsmInsOpcodes[cexp->mAsmInsType][cexp->mAsmInsMode];
|
||||
if (opcode < 0)
|
||||
mErrors->Error(cexp->mLocation, "Invalid opcode adressing mode");
|
||||
d[offset++] = opcode;
|
||||
}
|
||||
|
||||
Declaration* aexp = nullptr;
|
||||
if (cexp->mLeft)
|
||||
aexp = cexp->mLeft->mDecValue;
|
||||
|
||||
switch (cexp->mAsmInsMode)
|
||||
{
|
||||
case ASMIM_IMPLIED:
|
||||
break;
|
||||
case ASMIM_IMMEDIATE:
|
||||
if (aexp->mType == DT_CONST_INTEGER)
|
||||
d[offset++] = cexp->mLeft->mDecValue->mInteger & 255;
|
||||
else if (aexp->mType == DT_LABEL_REF)
|
||||
{
|
||||
if (aexp->mBase->mBase->mVarIndex < 0)
|
||||
{
|
||||
InterCodeBasicBlock* bblock = nullptr;
|
||||
TranslateExpression(procType, proc, bblock, aexp->mBase->mBase->mValue, breakBlock, continueBlock);
|
||||
}
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = aexp->mFlags & DTF_UPPER_BYTE;
|
||||
ref.mLower = !(aexp->mFlags & DTF_UPPER_BYTE);
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mBase->mBase->mVarIndex;
|
||||
ref.mOffset = aexp->mOffset + aexp->mBase->mInteger;
|
||||
|
||||
references.Push(ref);
|
||||
|
||||
offset += 1;
|
||||
}
|
||||
break;
|
||||
case ASMIM_ZERO_PAGE:
|
||||
case ASMIM_ZERO_PAGE_X:
|
||||
case ASMIM_INDIRECT_X:
|
||||
case ASMIM_INDIRECT_Y:
|
||||
d[offset++] = aexp->mInteger;
|
||||
break;
|
||||
case ASMIM_ABSOLUTE:
|
||||
case ASMIM_INDIRECT:
|
||||
case ASMIM_ABSOLUTE_X:
|
||||
case ASMIM_ABSOLUTE_Y:
|
||||
if (aexp->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
d[offset++] = cexp->mLeft->mDecValue->mInteger & 255;
|
||||
d[offset++] = cexp->mLeft->mDecValue->mInteger >> 8;
|
||||
}
|
||||
else if (aexp->mType == DT_LABEL)
|
||||
{
|
||||
if (aexp->mBase->mVarIndex < 0)
|
||||
{
|
||||
InterCodeBasicBlock* bblock = nullptr;
|
||||
TranslateExpression(procType, proc, bblock, aexp->mBase->mValue, breakBlock, continueBlock);
|
||||
}
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mBase->mVarIndex;
|
||||
ref.mOffset = aexp->mInteger;
|
||||
|
||||
references.Push(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
else if (aexp->mType == DT_LABEL_REF)
|
||||
{
|
||||
if (aexp->mBase->mBase->mVarIndex < 0)
|
||||
{
|
||||
InterCodeBasicBlock* bblock = nullptr;
|
||||
TranslateExpression(procType, proc, bblock, aexp->mBase->mBase->mValue, breakBlock, continueBlock);
|
||||
}
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mBase->mBase->mVarIndex;
|
||||
ref.mOffset = aexp->mOffset + aexp->mBase->mInteger;
|
||||
|
||||
references.Push(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
else if (aexp->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (aexp->mVarIndex < 0)
|
||||
{
|
||||
InterCodeBasicBlock* bblock = nullptr;
|
||||
TranslateExpression(procType, proc, bblock, aexp->mValue, breakBlock, continueBlock);
|
||||
}
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mVarIndex;
|
||||
ref.mOffset = 0;
|
||||
|
||||
references.Push(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
else if (aexp->mType == DT_VARIABLE)
|
||||
{
|
||||
if (aexp->mFlags & DTF_GLOBAL)
|
||||
{
|
||||
InitGlobalVariable(proc->mModule, aexp);
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mFunction = false;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mAddr = offset;
|
||||
ref.mIndex = aexp->mVarIndex;
|
||||
ref.mOffset = 0;
|
||||
|
||||
references.Push(ref);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ASMIM_RELATIVE:
|
||||
d[offset] = aexp->mInteger - offset - 1;
|
||||
offset++;
|
||||
break;
|
||||
}
|
||||
|
||||
cexp = cexp->mRight;
|
||||
}
|
||||
|
||||
assert(offset == osize);
|
||||
|
||||
InterVariable& ivar(proc->mModule->mGlobalVars[var.mIndex]);
|
||||
|
||||
ivar.mNumReferences = references.Size();
|
||||
if (ivar.mNumReferences)
|
||||
{
|
||||
ivar.mReferences = new InterVariable::Reference[ivar.mNumReferences];
|
||||
for (int i = 0; i < ivar.mNumReferences; i++)
|
||||
ivar.mReferences[i] = references[i];
|
||||
}
|
||||
Declaration* dec = exp->mDecValue;
|
||||
|
||||
if (block)
|
||||
{
|
||||
InterInstruction* ins = new InterInstruction();
|
||||
ins->mCode = IC_CONSTANT;
|
||||
ins->mTType = IT_POINTER;
|
||||
ins->mTTemp = proc->AddTemporary(ins->mTType);
|
||||
ins->mOperandSize = dec->mSize;
|
||||
ins->mIntValue = 0;
|
||||
ins->mMemory = IM_GLOBAL;
|
||||
ins->mVarIndex = var.mIndex;
|
||||
ins->mLinkerObject = dec->mLinkerObject;
|
||||
ins->mVarIndex = dec->mVarIndex;
|
||||
block->Append(ins);
|
||||
|
||||
InterInstruction * jins = new InterInstruction();
|
||||
|
@ -2233,7 +2071,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
}
|
||||
|
||||
void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int offset, Declaration* data, GrowingArray<InterVariable::Reference>& references)
|
||||
void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int offset, Declaration* data, InterVariable * variable)
|
||||
{
|
||||
if (data->mType == DT_CONST_DATA)
|
||||
{
|
||||
|
@ -2244,7 +2082,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
|
|||
Declaration* mdec = data->mParams;
|
||||
while (mdec)
|
||||
{
|
||||
BuildInitializer(mod, dp, offset + mdec->mOffset, mdec, references);
|
||||
BuildInitializer(mod, dp, offset + mdec->mOffset, mdec, variable);
|
||||
mdec = mdec->mNext;
|
||||
}
|
||||
}
|
||||
|
@ -2276,63 +2114,66 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
|
|||
}
|
||||
else if (data->mType == DT_CONST_ASSEMBLER)
|
||||
{
|
||||
if (data->mVarIndex < 0)
|
||||
if (!data->mLinkerObject)
|
||||
TranslateAssembler(mod, data->mValue);
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mAddr = offset;
|
||||
ref.mUpper = true;
|
||||
ref.mLower = true;
|
||||
ref.mFunction = false;
|
||||
ref.mIndex = data->mVarIndex;
|
||||
ref.mOffset = 0;
|
||||
references.Push(ref);
|
||||
LinkerReference ref;
|
||||
ref.mObject = variable->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
ref.mRefObject = data->mLinkerObject;
|
||||
ref.mRefOffset = 0;
|
||||
mLinker->AddReference(ref);
|
||||
}
|
||||
else if (data->mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
if (data->mVarIndex < 0)
|
||||
if (!data->mLinkerObject)
|
||||
{
|
||||
InterCodeProcedure* cproc = this->TranslateProcedure(mod, data->mValue, data);
|
||||
cproc->ReduceTemporaries();
|
||||
}
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mAddr = offset;
|
||||
ref.mLower = true;
|
||||
ref.mUpper = true;
|
||||
ref.mFunction = true;
|
||||
ref.mIndex = data->mVarIndex;
|
||||
ref.mOffset = 0;
|
||||
references.Push(ref);
|
||||
LinkerReference ref;
|
||||
ref.mObject = variable->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
ref.mRefObject = data->mLinkerObject;
|
||||
ref.mRefOffset = 0;
|
||||
mLinker->AddReference(ref);
|
||||
}
|
||||
else if (data->mType == DT_CONST_POINTER)
|
||||
{
|
||||
Expression* exp = data->mValue;
|
||||
Declaration* dec = exp->mDecValue;
|
||||
|
||||
InterVariable::Reference ref;
|
||||
ref.mAddr = offset;
|
||||
ref.mLower = true;
|
||||
ref.mUpper = true;
|
||||
LinkerReference ref;
|
||||
ref.mObject = variable->mLinkerObject;
|
||||
ref.mOffset = offset;
|
||||
ref.mHighByte = true;
|
||||
ref.mLowByte = true;
|
||||
|
||||
switch (dec->mType)
|
||||
{
|
||||
case DT_CONST_DATA:
|
||||
{
|
||||
if (dec->mVarIndex < 0)
|
||||
if (!dec->mLinkerObject)
|
||||
{
|
||||
dec->mVarIndex = mod->mGlobalVars.Size();
|
||||
InterVariable var;
|
||||
var.mIndex = dec->mVarIndex;
|
||||
var.mOffset = 0;
|
||||
var.mSize = dec->mSize;
|
||||
var.mData = dec->mData;
|
||||
var.mIdent = dec->mIdent;
|
||||
InterVariable* var = new InterVariable();
|
||||
var->mIndex = dec->mVarIndex;
|
||||
var->mOffset = 0;
|
||||
var->mSize = dec->mSize;
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
|
||||
dec->mLinkerObject = var->mLinkerObject;
|
||||
var->mLinkerObject->AddData(dec->mData, dec->mSize);
|
||||
mod->mGlobalVars.Push(var);
|
||||
}
|
||||
ref.mFunction = false;
|
||||
ref.mIndex = dec->mVarIndex;
|
||||
ref.mOffset = 0;
|
||||
references.Push(ref);
|
||||
|
||||
ref.mRefObject = dec->mLinkerObject;
|
||||
ref.mRefOffset = 0;
|
||||
mLinker->AddReference(ref);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2381,8 +2222,10 @@ void InterCodeGenerator::TranslateLogic(Declaration* procType, InterCodeProcedur
|
|||
|
||||
InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod, Expression* exp, Declaration * dec)
|
||||
{
|
||||
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent);
|
||||
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent, mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_BYTE_CODE));
|
||||
|
||||
dec->mVarIndex = proc->mID;
|
||||
dec->mLinkerObject = proc->mLinkerObject;
|
||||
|
||||
if (mForceNativeCode)
|
||||
dec->mFlags |= DTF_NATIVE;
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
#include "Parser.h"
|
||||
#include "InterCode.h"
|
||||
#include "Linker.h"
|
||||
|
||||
class InterCodeGenerator
|
||||
{
|
||||
public:
|
||||
InterCodeGenerator(Errors * errors);
|
||||
InterCodeGenerator(Errors * errors, Linker * linker);
|
||||
~InterCodeGenerator(void);
|
||||
|
||||
struct ExValue
|
||||
|
@ -27,11 +28,12 @@ public:
|
|||
protected:
|
||||
|
||||
Errors* mErrors;
|
||||
Linker* mLinker;
|
||||
|
||||
ExValue Dereference(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, int level = 0);
|
||||
ExValue CoerceType(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, Declaration * type);
|
||||
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock);
|
||||
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp);
|
||||
|
||||
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, GrowingArray<InterVariable::Reference> & references);
|
||||
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable);
|
||||
};
|
||||
|
|
|
@ -2,6 +2,22 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
void LinkerObject::AddData(const uint8* data, int size)
|
||||
{
|
||||
mSize = size;
|
||||
mData = new uint8[size];
|
||||
memcpy(mData, data, size);
|
||||
}
|
||||
|
||||
uint8* LinkerObject::AddSpace(int size)
|
||||
{
|
||||
mSize = size;
|
||||
mData = new uint8[size];
|
||||
memset(mData, 0, size);
|
||||
return mData;
|
||||
}
|
||||
|
||||
Linker::Linker(Errors* errors)
|
||||
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr)
|
||||
{
|
||||
|
@ -25,7 +41,7 @@ int Linker::AddSection(const Ident* section, int start, int size)
|
|||
return lsec->mID;
|
||||
}
|
||||
|
||||
int Linker::AddObject(const Location& location, const Ident* ident, const Ident* section, LinkerObjectType type)
|
||||
LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, const Ident* section, LinkerObjectType type)
|
||||
{
|
||||
LinkerObject* obj = new LinkerObject;
|
||||
obj->mLocation = location;
|
||||
|
@ -36,31 +52,9 @@ int Linker::AddObject(const Location& location, const Ident* ident, const Ident*
|
|||
obj->mIdent = ident;
|
||||
obj->mSection = section;
|
||||
obj->mProc = nullptr;
|
||||
obj->mReferenced = false;
|
||||
mObjects.Push(obj);
|
||||
return obj->mID;
|
||||
}
|
||||
|
||||
void Linker::AddObjectData(int id, const uint8* data, int size)
|
||||
{
|
||||
LinkerObject* obj = mObjects[id];
|
||||
obj->mSize = size;
|
||||
obj->mData = new uint8[size];
|
||||
memcpy(obj->mData, data, size);
|
||||
}
|
||||
|
||||
uint8* Linker::AddObjectSpace(int id, int size)
|
||||
{
|
||||
LinkerObject* obj = mObjects[id];
|
||||
obj->mSize = size;
|
||||
obj->mData = new uint8[size];
|
||||
memset(obj->mData, 0, size);
|
||||
return obj->mData;
|
||||
}
|
||||
|
||||
void Linker::AttachObjectProcedure(int id, InterCodeProcedure* proc)
|
||||
{
|
||||
LinkerObject* obj = mObjects[id];
|
||||
obj->mProc = proc;
|
||||
return obj;
|
||||
}
|
||||
|
||||
void Linker::AddReference(const LinkerReference& ref)
|
||||
|
@ -69,30 +63,46 @@ void Linker::AddReference(const LinkerReference& ref)
|
|||
mReferences.Push(nref);
|
||||
}
|
||||
|
||||
void Linker::ReferenceObject(LinkerObject* obj)
|
||||
{
|
||||
if (!obj->mReferenced)
|
||||
{
|
||||
obj->mReferenced = true;
|
||||
for (int i = 0; i < mReferences.Size(); i++)
|
||||
{
|
||||
LinkerReference* ref = mReferences[i];
|
||||
if (ref->mObject == obj)
|
||||
ReferenceObject(ref->mRefObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Linker::Link(void)
|
||||
{
|
||||
for (int i = 0; i < mObjects.Size(); i++)
|
||||
{
|
||||
LinkerObject* obj = mObjects[i];
|
||||
LinkerSection* lsec;
|
||||
int j = 0;
|
||||
while (j < mSections.Size() && !(mSections[j]->mIdent == obj->mSection && mSections[j]->mUsed + obj->mSize <= mSections[j]->mSize))
|
||||
j++;
|
||||
if (j < mSections.Size())
|
||||
if (obj->mReferenced)
|
||||
{
|
||||
LinkerSection* lsec = mSections[j];
|
||||
obj->mLinkerSection = lsec;
|
||||
obj->mAddress = lsec->mUsed;
|
||||
lsec->mUsed += obj->mSize;
|
||||
memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize);
|
||||
LinkerSection* lsec;
|
||||
int j = 0;
|
||||
while (j < mSections.Size() && !(mSections[j]->mIdent == obj->mSection && mSections[j]->mUsed + obj->mSize <= mSections[j]->mSize))
|
||||
j++;
|
||||
if (j < mSections.Size())
|
||||
{
|
||||
LinkerSection* lsec = mSections[j];
|
||||
obj->mLinkerSection = lsec;
|
||||
obj->mAddress = lsec->mUsed;
|
||||
lsec->mUsed += obj->mSize;
|
||||
}
|
||||
else
|
||||
mErrors->Error(obj->mLocation, "Out of space in section", obj->mSection->mString);
|
||||
}
|
||||
else
|
||||
mErrors->Error(obj->mLocation, "Out of space in section", obj->mSection->mString);
|
||||
}
|
||||
|
||||
if (mErrors->mErrorCount == 0)
|
||||
{
|
||||
mProgramStart = 0xffff;
|
||||
mProgramStart = 0x0801;
|
||||
mProgramEnd = 0x0801;
|
||||
|
||||
int address = 0;
|
||||
|
@ -114,23 +124,29 @@ void Linker::Link(void)
|
|||
for (int i = 0; i < mObjects.Size(); i++)
|
||||
{
|
||||
LinkerObject* obj = mObjects[i];
|
||||
obj->mAddress += obj->mLinkerSection->mStart;
|
||||
if (obj->mReferenced)
|
||||
{
|
||||
obj->mAddress += obj->mLinkerSection->mStart;
|
||||
memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mReferences.Size(); i++)
|
||||
{
|
||||
LinkerReference* ref = mReferences[i];
|
||||
LinkerObject* obj = mObjects[ref->mID];
|
||||
LinkerObject* robj = mObjects[ref->mRefID];
|
||||
LinkerObject* obj = ref->mObject;
|
||||
if (obj->mReferenced)
|
||||
{
|
||||
LinkerObject* robj = ref->mRefObject;
|
||||
|
||||
int raddr = robj->mAddress + ref->mRefOffset;
|
||||
uint8* dp = mMemory + obj->mAddress + ref->mOffset;
|
||||
|
||||
if (ref->mLowByte)
|
||||
*dp++ = raddr & 0xff;
|
||||
if (ref->mHighByte)
|
||||
*dp++ = (raddr >> 8) & 0xff;
|
||||
int raddr = robj->mAddress + ref->mRefOffset;
|
||||
uint8* dp = mMemory + obj->mAddress + ref->mOffset;
|
||||
|
||||
if (ref->mLowByte)
|
||||
*dp++ = raddr & 0xff;
|
||||
if (ref->mHighByte)
|
||||
*dp++ = (raddr >> 8) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,10 +191,13 @@ bool Linker::WriteMapFile(const char* filename)
|
|||
{
|
||||
LinkerObject* obj = mObjects[i];
|
||||
|
||||
if (obj->mIdent)
|
||||
fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
|
||||
else
|
||||
fprintf(file, "%04x - %04x : *, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
|
||||
if (obj->mReferenced)
|
||||
{
|
||||
if (obj->mIdent)
|
||||
fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
|
||||
else
|
||||
fprintf(file, "%04x - %04x : *, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
@ -199,14 +218,17 @@ bool Linker::WriteAsmFile(const char* filename)
|
|||
{
|
||||
LinkerObject* obj = mObjects[i];
|
||||
|
||||
switch (obj->mType)
|
||||
if (obj->mReferenced)
|
||||
{
|
||||
case LOT_BYTE_CODE:
|
||||
mByteCodeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc);
|
||||
break;
|
||||
case LOT_NATIVE_CODE:
|
||||
mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc);
|
||||
break;
|
||||
switch (obj->mType)
|
||||
{
|
||||
case LOT_BYTE_CODE:
|
||||
mByteCodeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent);
|
||||
break;
|
||||
case LOT_NATIVE_CODE:
|
||||
mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,22 +21,27 @@ enum LinkerObjectType
|
|||
LOT_STACK
|
||||
};
|
||||
|
||||
struct LinkerReference
|
||||
class LinkerObject;
|
||||
|
||||
class LinkerReference
|
||||
{
|
||||
int mID, mOffset;
|
||||
int mRefID, mRefOffset;
|
||||
public:
|
||||
LinkerObject* mObject, * mRefObject;
|
||||
int mOffset, mRefOffset;
|
||||
bool mLowByte, mHighByte;
|
||||
};
|
||||
|
||||
struct LinkerSection
|
||||
class LinkerSection
|
||||
{
|
||||
public:
|
||||
const Ident* mIdent;
|
||||
int mID;
|
||||
int mStart, mSize, mUsed;
|
||||
};
|
||||
|
||||
struct LinkerObject
|
||||
class LinkerObject
|
||||
{
|
||||
public:
|
||||
Location mLocation;
|
||||
const Ident* mIdent, * mSection;
|
||||
LinkerObjectType mType;
|
||||
|
@ -46,6 +51,10 @@ struct LinkerObject
|
|||
LinkerSection* mLinkerSection;
|
||||
uint8* mData;
|
||||
InterCodeProcedure* mProc;
|
||||
bool mReferenced;
|
||||
|
||||
void AddData(const uint8* data, int size);
|
||||
uint8* AddSpace(int size);
|
||||
};
|
||||
|
||||
class Linker
|
||||
|
@ -56,10 +65,7 @@ public:
|
|||
|
||||
int AddSection(const Ident* section, int start, int size);
|
||||
|
||||
int AddObject(const Location & location, const Ident* ident, const Ident* section, LinkerObjectType type);
|
||||
void AddObjectData(int id, const uint8* data, int size);
|
||||
uint8 * AddObjectSpace(int id, int size);
|
||||
void AttachObjectProcedure(int id, InterCodeProcedure* proc);
|
||||
LinkerObject * AddObject(const Location & location, const Ident* ident, const Ident* section, LinkerObjectType type);
|
||||
|
||||
void AddReference(const LinkerReference& ref);
|
||||
|
||||
|
@ -72,13 +78,14 @@ public:
|
|||
GrowingArray<LinkerObject*> mObjects;
|
||||
|
||||
uint8 mMemory[0x10000];
|
||||
int mProgramStart, mProgramEnd;
|
||||
|
||||
void ReferenceObject(LinkerObject* obj);
|
||||
|
||||
void Link(void);
|
||||
protected:
|
||||
NativeCodeDisassembler mNativeDisassembler;
|
||||
ByteCodeDisassembler mByteCodeDisassembler;
|
||||
|
||||
int mProgramStart, mProgramEnd;
|
||||
|
||||
Errors* mErrors;
|
||||
};
|
||||
|
|
|
@ -44,16 +44,8 @@ void NativeRegisterDataSet::ResetZeroPage(int addr)
|
|||
}
|
||||
}
|
||||
|
||||
NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, AsmInsMode mode, int address, int varIndex, bool lower, bool upper)
|
||||
: mType(type), mMode(mode), mAddress(address), mVarIndex(varIndex), mLower(lower), mUpper(upper), mRuntime(nullptr), mFunction(false)
|
||||
{}
|
||||
|
||||
NativeCodeInstruction::NativeCodeInstruction(const char* runtime)
|
||||
: mType(ASMIT_JSR), mMode(ASMIM_ABSOLUTE), mAddress(0), mVarIndex(0), mLower(true), mUpper(true), mRuntime(runtime), mFunction(false)
|
||||
{}
|
||||
|
||||
NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, AsmInsMode mode, const char* runtime, int address, bool lower, bool upper)
|
||||
: mType(type), mMode(mode), mAddress(address), mVarIndex(0), mLower(lower), mUpper(upper), mRuntime(runtime), mFunction(false)
|
||||
NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, AsmInsMode mode, int address, LinkerObject* linkerObject, uint32 flags)
|
||||
: mType(type), mMode(mode), mAddress(address), mLinkerObject(linkerObject), mFlags(flags)
|
||||
{}
|
||||
|
||||
bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
|
||||
|
@ -82,14 +74,19 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
|
|||
requiredTemps -= CPU_REG_X;
|
||||
requiredTemps -= CPU_REG_Y;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (mFlags & NCIF_RUNTIME)
|
||||
{
|
||||
requiredTemps += BC_REG_ACCU + i;
|
||||
requiredTemps += BC_REG_WORK + i;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
requiredTemps += BC_REG_ACCU + i;
|
||||
requiredTemps += BC_REG_WORK + i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
requiredTemps += BC_REG_LOCALS;
|
||||
requiredTemps += BC_REG_LOCALS + 1;
|
||||
}
|
||||
|
||||
requiredTemps += BC_REG_LOCALS;
|
||||
requiredTemps += BC_REG_LOCALS + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -468,7 +465,7 @@ bool NativeCodeInstruction::SameEffectiveAddress(const NativeCodeInstruction& in
|
|||
case ASMIM_ABSOLUTE:
|
||||
case ASMIM_ABSOLUTE_X:
|
||||
case ASMIM_ABSOLUTE_Y:
|
||||
return (ins.mVarIndex == mVarIndex && ins.mAddress == mAddress && ins.mFunction == mFunction && ins.mRuntime == mRuntime);
|
||||
return (ins.mLinkerObject == mLinkerObject && ins.mAddress == mAddress);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -549,9 +546,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_A].mImmediate)
|
||||
{
|
||||
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mImmediate - mAddress;
|
||||
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue - mAddress;
|
||||
data.mRegs[CPU_REG_C].mImmediate = true;
|
||||
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_A].mImmediate >= mAddress;
|
||||
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_A].mValue >= mAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -563,9 +560,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_X].mImmediate)
|
||||
{
|
||||
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mImmediate - mAddress;
|
||||
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mValue - mAddress;
|
||||
data.mRegs[CPU_REG_C].mImmediate = true;
|
||||
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_X].mImmediate >= mAddress;
|
||||
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_X].mValue >= mAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -577,9 +574,9 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_Y].mImmediate)
|
||||
{
|
||||
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mImmediate - mAddress;
|
||||
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mValue - mAddress;
|
||||
data.mRegs[CPU_REG_C].mImmediate = true;
|
||||
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_Y].mImmediate >= mAddress;
|
||||
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_Y].mValue >= mAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1158,16 +1155,16 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
|
|||
break;
|
||||
case ASMIM_IMMEDIATE:
|
||||
case ASMIM_IMMEDIATE_ADDRESS:
|
||||
if (mVarIndex != -1)
|
||||
if (mLinkerObject)
|
||||
{
|
||||
ByteCodeRelocation rl;
|
||||
rl.mAddr = block->mCode.Size();
|
||||
rl.mFunction = mFunction;
|
||||
rl.mLower = mLower;
|
||||
rl.mUpper = mUpper;
|
||||
rl.mIndex = mVarIndex;
|
||||
rl.mOffset = mAddress;
|
||||
rl.mRuntime = nullptr;
|
||||
LinkerReference rl;
|
||||
rl.mOffset = block->mCode.Size();
|
||||
rl.mLowByte = mFlags & NCIF_LOWER;
|
||||
rl.mHighByte = mFlags & NCIF_UPPER;
|
||||
rl.mRefObject = mLinkerObject;
|
||||
|
||||
rl.mRefObject = mLinkerObject;
|
||||
rl.mRefOffset = mAddress;
|
||||
block->mRelocations.Push(rl);
|
||||
block->PutByte(0);
|
||||
}
|
||||
|
@ -1180,29 +1177,14 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
|
|||
case ASMIM_INDIRECT:
|
||||
case ASMIM_ABSOLUTE_X:
|
||||
case ASMIM_ABSOLUTE_Y:
|
||||
if (mRuntime)
|
||||
if (mLinkerObject)
|
||||
{
|
||||
ByteCodeRelocation rl;
|
||||
rl.mAddr = block->mCode.Size();
|
||||
rl.mFunction = mFunction;
|
||||
rl.mLower = true;
|
||||
rl.mUpper = true;
|
||||
rl.mIndex = -1;
|
||||
rl.mOffset = mAddress;
|
||||
rl.mRuntime = mRuntime;
|
||||
block->mRelocations.Push(rl);
|
||||
block->PutWord(0);
|
||||
}
|
||||
else if (mVarIndex != -1)
|
||||
{
|
||||
ByteCodeRelocation rl;
|
||||
rl.mAddr = block->mCode.Size();
|
||||
rl.mFunction = mFunction;;
|
||||
rl.mLower = true;
|
||||
rl.mUpper = true;
|
||||
rl.mIndex = mVarIndex;
|
||||
rl.mOffset = mAddress;
|
||||
rl.mRuntime = nullptr;
|
||||
LinkerReference rl;
|
||||
rl.mOffset = block->mCode.Size();
|
||||
rl.mLowByte = true;
|
||||
rl.mHighByte = true;
|
||||
rl.mRefObject = mLinkerObject;
|
||||
rl.mRefOffset = mAddress;
|
||||
block->mRelocations.Push(rl);
|
||||
block->PutWord(0);
|
||||
}
|
||||
|
@ -1265,14 +1247,13 @@ int NativeCodeBasicBlock::PutJump(NativeCodeProcedure* proc, int offset)
|
|||
{
|
||||
PutByte(0x4c);
|
||||
|
||||
ByteCodeRelocation rl;
|
||||
rl.mAddr = mCode.Size();
|
||||
rl.mFunction = true;
|
||||
rl.mLower = true;
|
||||
rl.mUpper = true;
|
||||
rl.mIndex = proc->mIndex;
|
||||
rl.mOffset = mOffset + mCode.Size() + offset - 1;
|
||||
rl.mRuntime = nullptr;
|
||||
LinkerReference rl;
|
||||
rl.mObject = nullptr;
|
||||
rl.mOffset = mCode.Size();
|
||||
rl.mLowByte = true;
|
||||
rl.mHighByte = true;
|
||||
rl.mRefObject = nullptr;
|
||||
rl.mRefOffset = mOffset + mCode.Size() + offset - 1;
|
||||
mRelocations.Push(rl);
|
||||
|
||||
PutWord(0);
|
||||
|
@ -1293,14 +1274,13 @@ int NativeCodeBasicBlock::PutBranch(NativeCodeProcedure* proc, AsmInsType code,
|
|||
PutByte(3);
|
||||
PutByte(0x4c);
|
||||
|
||||
ByteCodeRelocation rl;
|
||||
rl.mAddr = mCode.Size();
|
||||
rl.mFunction = true;
|
||||
rl.mLower = true;
|
||||
rl.mUpper = true;
|
||||
rl.mIndex = proc->mIndex;
|
||||
rl.mOffset = mOffset + mCode.Size() + offset - 3;
|
||||
rl.mRuntime = nullptr;
|
||||
LinkerReference rl;
|
||||
rl.mObject = nullptr;
|
||||
rl.mOffset = mCode.Size();
|
||||
rl.mLowByte = true;
|
||||
rl.mHighByte = true;
|
||||
rl.mRefObject = nullptr;
|
||||
rl.mRefOffset = mOffset + mCode.Size() + offset - 3;
|
||||
mRelocations.Push(rl);
|
||||
|
||||
PutWord(0);
|
||||
|
@ -1328,9 +1308,9 @@ void NativeCodeBasicBlock::LoadConstantToReg(InterCodeProcedure * proc, const In
|
|||
{
|
||||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mIntValue, ins->mVarIndex, true, false));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mIntValue, ins->mLinkerObject, NCIF_LOWER));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mIntValue, ins->mVarIndex, false, true));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mIntValue, ins->mLinkerObject, NCIF_UPPER));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
|
@ -1345,7 +1325,7 @@ void NativeCodeBasicBlock::LoadConstantToReg(InterCodeProcedure * proc, const In
|
|||
int index = ins->mIntValue;
|
||||
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(areg, index, 2);
|
||||
|
@ -1363,10 +1343,8 @@ void NativeCodeBasicBlock::LoadConstantToReg(InterCodeProcedure * proc, const In
|
|||
}
|
||||
else if (ins->mMemory == IM_PROCEDURE)
|
||||
{
|
||||
NativeCodeInstruction lins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mVarIndex, true, false);
|
||||
lins.mFunction = ins->mMemory == IM_PROCEDURE;
|
||||
NativeCodeInstruction hins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mVarIndex, false, true);
|
||||
hins.mFunction = ins->mMemory == IM_PROCEDURE;
|
||||
NativeCodeInstruction lins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mLinkerObject, NCIF_LOWER);
|
||||
NativeCodeInstruction hins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mLinkerObject, NCIF_UPPER);
|
||||
|
||||
mIns.Push(lins);
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
|
@ -1422,13 +1400,13 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 2, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 2, ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 3, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 3, ins->mLinkerObject));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1446,7 +1424,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
int index = ins->mSIntConst[1];
|
||||
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(reg, index, 4);
|
||||
|
@ -1496,13 +1474,13 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 2, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 2, ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 3, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 3, ins->mLinkerObject));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1520,7 +1498,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
int index = ins->mSIntConst[1];
|
||||
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(reg, index, 4);
|
||||
|
@ -1606,9 +1584,9 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[0] & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[0] >> 8) & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mLinkerObject));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1622,7 +1600,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
int index = ins->mSIntConst[1];
|
||||
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(reg, index, 2);
|
||||
|
@ -1651,9 +1629,9 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mLinkerObject));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1667,7 +1645,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
int index = ins->mSIntConst[1];
|
||||
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(reg, index, 2);
|
||||
|
@ -1731,7 +1709,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[0] & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mLinkerObject));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1743,7 +1721,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
int index = ins->mSIntConst[1];
|
||||
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(reg, index, 1);
|
||||
|
@ -1766,9 +1744,9 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[0] & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[0] >> 8) & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mLinkerObject));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1782,7 +1760,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
int index = ins->mSIntConst[1];
|
||||
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(reg, index, 2);
|
||||
|
@ -1814,7 +1792,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mLinkerObject));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1826,7 +1804,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
int index = ins->mSIntConst[1];
|
||||
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(reg, index, 1);
|
||||
|
@ -1849,9 +1827,9 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1], ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSIntConst[1] + 1, ins->mLinkerObject));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1866,7 +1844,7 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
|
|||
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(reg, index, 2);
|
||||
|
@ -1951,7 +1929,7 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
if (rins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, rins->mSIntConst[0], rins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, rins->mSIntConst[0], rins->mLinkerObject));
|
||||
}
|
||||
else if (rins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1962,7 +1940,7 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI
|
|||
int index = rins->mSIntConst[0];
|
||||
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (rins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[rins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[rins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += rins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(areg, index, 4);
|
||||
|
@ -1984,7 +1962,7 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
if (wins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, wins->mSIntConst[1], wins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, wins->mSIntConst[1], wins->mLinkerObject));
|
||||
}
|
||||
else if (wins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -1995,7 +1973,7 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI
|
|||
int index = wins->mSIntConst[1];
|
||||
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (wins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[wins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[wins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += wins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(areg, index, 1);
|
||||
|
@ -2031,13 +2009,13 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 1, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 1, ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 2, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 2, ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 3, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 3, ins->mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
|
@ -2056,7 +2034,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
int index = ins->mSIntConst[0];
|
||||
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(areg, index, 4);
|
||||
|
@ -2100,7 +2078,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mLinkerObject));
|
||||
if (ainsl)
|
||||
{
|
||||
if (ainsl->mType == ASMIT_ADC)
|
||||
|
@ -2110,7 +2088,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
mIns.Push(*ainsl);
|
||||
}
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 1, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 1, ins->mLinkerObject));
|
||||
if (ainsh) mIns.Push(*ainsh);
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
}
|
||||
|
@ -2135,7 +2113,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
int index = ins->mSIntConst[0];
|
||||
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(areg, index, 2);
|
||||
|
@ -2193,7 +2171,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mLinkerObject));
|
||||
}
|
||||
else if (ins->mMemory == IM_ABSOLUTE)
|
||||
{
|
||||
|
@ -2204,7 +2182,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
int index = ins->mSIntConst[0];
|
||||
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(areg, index, 2);
|
||||
|
@ -2234,7 +2212,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
if (ins->mMemory == IM_GLOBAL)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mLinkerObject));
|
||||
if (ainsl)
|
||||
{
|
||||
if (ainsl->mType == ASMIT_ADC)
|
||||
|
@ -2244,7 +2222,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
mIns.Push(*ainsl);
|
||||
}
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 1, ins->mVarIndex));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSIntConst[0] + 1, ins->mLinkerObject));
|
||||
if (ainsh) mIns.Push(*ainsh);
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||
}
|
||||
|
@ -2269,7 +2247,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
int index = ins->mSIntConst[0];
|
||||
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
|
||||
if (ins->mMemory == IM_LOCAL)
|
||||
index += proc->mLocalVars[ins->mVarIndex].mOffset;
|
||||
index += proc->mLocalVars[ins->mVarIndex]->mOffset;
|
||||
else
|
||||
index += ins->mVarIndex + proc->mLocalSize + 2;
|
||||
CheckFrameIndex(areg, index, 2);
|
||||
|
@ -2437,7 +2415,7 @@ void NativeCodeBasicBlock::ShiftRegisterLeft(InterCodeProcedure* proc, int reg,
|
|||
}
|
||||
}
|
||||
|
||||
int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins, int index, int mul)
|
||||
int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins, int index, int mul)
|
||||
{
|
||||
if (sins)
|
||||
LoadValueToReg(proc, sins, BC_REG_ACCU, nullptr, nullptr);
|
||||
|
@ -2499,7 +2477,8 @@ int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, const InterIns
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[1] & 0xff));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
|
||||
|
||||
mIns.Push(NativeCodeInstruction("mul16by8"));
|
||||
NativeCodeGenerator::Runtime& rt(nproc->mGenerator->ResolveRuntime(Ident::Unique("mul16by8")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, rt.mOffset, rt.mLinkerObject, NCIF_RUNTIME));
|
||||
|
||||
return BC_REG_WORK + 2;
|
||||
}
|
||||
|
@ -2522,7 +2501,7 @@ static int Binlog(unsigned n)
|
|||
|
||||
return k;
|
||||
}
|
||||
void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction * sins1, const InterInstruction * sins0)
|
||||
void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction * sins1, const InterInstruction * sins0)
|
||||
{
|
||||
int treg = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||
|
||||
|
@ -2597,25 +2576,35 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
|
||||
}
|
||||
|
||||
mIns.Push(NativeCodeInstruction("fsplitt"));
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("fsplitt")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_ADD:
|
||||
mIns.Push(NativeCodeInstruction("faddsub"));
|
||||
break;
|
||||
{
|
||||
NativeCodeGenerator::Runtime& art(nproc->mGenerator->ResolveRuntime(Ident::Unique("faddsub")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, art.mOffset, art.mLinkerObject, NCIF_RUNTIME));
|
||||
} break;
|
||||
case IA_SUB:
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0x80));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
|
||||
mIns.Push(NativeCodeInstruction("faddsub"));
|
||||
break;
|
||||
NativeCodeGenerator::Runtime& art(nproc->mGenerator->ResolveRuntime(Ident::Unique("faddsub")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, art.mOffset, art.mLinkerObject, NCIF_RUNTIME));
|
||||
} break;
|
||||
case IA_MUL:
|
||||
mIns.Push(NativeCodeInstruction("fmul"));
|
||||
break;
|
||||
{
|
||||
NativeCodeGenerator::Runtime& art(nproc->mGenerator->ResolveRuntime(Ident::Unique("fmul")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, art.mOffset, art.mLinkerObject, NCIF_RUNTIME));
|
||||
} break;
|
||||
case IA_DIVS:
|
||||
case IA_DIVU:
|
||||
mIns.Push(NativeCodeInstruction("fdiv"));
|
||||
break;
|
||||
{
|
||||
NativeCodeGenerator::Runtime& art(nproc->mGenerator->ResolveRuntime(Ident::Unique("fdiv")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, art.mOffset, art.mLinkerObject, NCIF_RUNTIME));
|
||||
} break;
|
||||
}
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
|
@ -2826,11 +2815,11 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
|
|||
|
||||
if (ins->mOperator == IA_MUL && ins->mSTemp[1] < 0 && (ins->mSIntConst[1] & ~0xff) == 0)
|
||||
{
|
||||
reg = ShortMultiply(proc, ins, sins0, 0, ins->mSIntConst[1] & 0xff);
|
||||
reg = ShortMultiply(proc, nproc, ins, sins0, 0, ins->mSIntConst[1] & 0xff);
|
||||
}
|
||||
else if (ins->mOperator == IA_MUL && ins->mSTemp[0] < 0 && (ins->mSIntConst[0] & ~0xff) == 0)
|
||||
{
|
||||
reg = ShortMultiply(proc, ins, sins1, 1, ins->mSIntConst[0] & 0xff);
|
||||
reg = ShortMultiply(proc, nproc, ins, sins1, 1, ins->mSIntConst[0] & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2871,23 +2860,33 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
|
|||
switch (ins->mOperator)
|
||||
{
|
||||
case IA_MUL:
|
||||
mIns.Push(NativeCodeInstruction("mul16"));
|
||||
{
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("mul16")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
reg = BC_REG_WORK + 2;
|
||||
break;
|
||||
} break;
|
||||
case IA_DIVS:
|
||||
mIns.Push(NativeCodeInstruction("divs16"));
|
||||
break;
|
||||
{
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("divs16")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
} break;
|
||||
case IA_MODS:
|
||||
mIns.Push(NativeCodeInstruction("mods16"));
|
||||
{
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("mods16")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
reg = BC_REG_WORK + 2;
|
||||
break;
|
||||
} break;
|
||||
case IA_DIVU:
|
||||
mIns.Push(NativeCodeInstruction("divu16"));
|
||||
break;
|
||||
{
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("divu16")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
} break;
|
||||
case IA_MODU:
|
||||
mIns.Push(NativeCodeInstruction("modu16"));
|
||||
{
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("modu16")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
reg = BC_REG_WORK + 2;
|
||||
break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2962,12 +2961,14 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 0x0f));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
|
||||
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("bitshift")));
|
||||
|
||||
if (l < 8)
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, "bitshift", 8 + l));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset + 8 + l, frt.mLinkerObject));
|
||||
else
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, "bitshift", l));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset + l, frt.mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
else
|
||||
|
@ -3070,9 +3071,11 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 0x0f));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, "bitshift", 39 - l));
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("bitshift")));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset + 39 - l, frt.mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, "bitshift", 47 - l));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset + 47 - l, frt.mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
else
|
||||
|
@ -3158,21 +3161,23 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 0x0f));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
|
||||
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("bitshift")));
|
||||
|
||||
if (l == 15)
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ABSOLUTE_X, "bitshift", 39 - l));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ABSOLUTE_X, frt.mOffset + 39 - l, frt.mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, "bitshift", 47 - l));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset + 47 - l, frt.mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, "bitshift", 39 - l));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset + 39 - l, frt.mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, "bitshift", 47 - l));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, frt.mOffset + 47 - l, frt.mLinkerObject));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
|
||||
}
|
||||
}
|
||||
|
@ -3216,7 +3221,7 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
|
|||
}
|
||||
}
|
||||
|
||||
void NativeCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, const InterInstruction * ins)
|
||||
void NativeCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins)
|
||||
{
|
||||
int treg = BC_REG_TMP + proc->mTempOffset[ins->mTTemp];
|
||||
|
||||
|
@ -3258,9 +3263,15 @@ void NativeCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, const InterIn
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
|
||||
if (ins->mOperator == IA_FLOOR)
|
||||
mIns.Push(NativeCodeInstruction("ffloor"));
|
||||
{
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ffloor")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
}
|
||||
else
|
||||
mIns.Push(NativeCodeInstruction("fceil"));
|
||||
{
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("fceil")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
}
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 0));
|
||||
|
@ -3299,7 +3310,7 @@ void NativeCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, const InterIn
|
|||
}
|
||||
}
|
||||
|
||||
void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const InterInstruction * ins)
|
||||
void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins)
|
||||
{
|
||||
switch (ins->mOperator)
|
||||
{
|
||||
|
@ -3314,7 +3325,8 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Int
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 3));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
|
||||
mIns.Push(NativeCodeInstruction("ftoi"));
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ftoi")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 0));
|
||||
|
@ -3329,7 +3341,8 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Int
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
|
||||
mIns.Push(NativeCodeInstruction("ffromi"));
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ffromi")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 0));
|
||||
|
@ -3431,7 +3444,8 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
|
||||
}
|
||||
|
||||
mIns.Push(NativeCodeInstruction("fcmp"));
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("fcmp")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
|
||||
switch (op)
|
||||
{
|
||||
|
@ -3601,14 +3615,12 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const
|
|||
}
|
||||
}
|
||||
|
||||
void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, const InterInstruction * ins)
|
||||
void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, NativeCodeProcedure * nproc, const InterInstruction * ins)
|
||||
{
|
||||
if (ins->mSTemp[0] < 0)
|
||||
{
|
||||
NativeCodeInstruction lins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mVarIndex, true, false);
|
||||
lins.mFunction = ins->mMemory == IM_PROCEDURE;
|
||||
NativeCodeInstruction hins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mVarIndex, false, true);
|
||||
hins.mFunction = ins->mMemory == IM_PROCEDURE;
|
||||
NativeCodeInstruction lins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mLinkerObject, NCIF_LOWER);
|
||||
NativeCodeInstruction hins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSIntConst[0], ins->mLinkerObject, NCIF_UPPER);
|
||||
|
||||
mIns.Push(lins);
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU));
|
||||
|
@ -3623,7 +3635,8 @@ void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, const InterIns
|
|||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
}
|
||||
|
||||
mIns.Push(NativeCodeInstruction("bcexec"));
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("bcexec")));
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME));
|
||||
|
||||
if (ins->mTTemp >= 0)
|
||||
{
|
||||
|
@ -3650,9 +3663,7 @@ void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, const InterIns
|
|||
|
||||
void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins)
|
||||
{
|
||||
NativeCodeInstruction ains(ASMIT_JSR, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mVarIndex, true, true);
|
||||
ains.mFunction = ins->mMemory == IM_PROCEDURE;
|
||||
mIns.Push(ains);
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mLinkerObject));
|
||||
|
||||
if (ins->mTTemp >= 0)
|
||||
{
|
||||
|
@ -3873,7 +3884,7 @@ bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
|
|||
return false;
|
||||
if (mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress && mIns[j].ChangesAddress())
|
||||
return false;
|
||||
if (mIns[j].mMode == ASMIM_ABSOLUTE_Y && mIns[j].mAddress <= mIns[at + 1].mAddress && mIns[j].mType == ASMIT_LDA && mIns[j].mVarIndex < 0)
|
||||
if (mIns[j].mMode == ASMIM_ABSOLUTE_Y && mIns[j].mAddress <= mIns[at + 1].mAddress && mIns[j].mType == ASMIT_LDA && !mIns[j].mLinkerObject)
|
||||
return false;
|
||||
if (mIns[j].mType == ASMIT_JSR)
|
||||
return false;
|
||||
|
@ -4251,8 +4262,8 @@ void NativeCodeBasicBlock::CopyCode(NativeCodeProcedure * proc, uint8* target)
|
|||
|
||||
for (int i = 0; i < mRelocations.Size(); i++)
|
||||
{
|
||||
ByteCodeRelocation& rl(mRelocations[i]);
|
||||
rl.mAddr += mOffset;
|
||||
LinkerReference& rl(mRelocations[i]);
|
||||
rl.mOffset += mOffset;
|
||||
proc->mRelocations.Push(rl);
|
||||
}
|
||||
|
||||
|
@ -4397,8 +4408,8 @@ NativeCodeBasicBlock::~NativeCodeBasicBlock(void)
|
|||
|
||||
}
|
||||
|
||||
NativeCodeProcedure::NativeCodeProcedure(void)
|
||||
: mRelocations({ 0 }), mBlocks(nullptr)
|
||||
NativeCodeProcedure::NativeCodeProcedure(NativeCodeGenerator* generator)
|
||||
: mGenerator(generator), mRelocations({ 0 }), mBlocks(nullptr)
|
||||
{
|
||||
mTempBlocks = 1000;
|
||||
}
|
||||
|
@ -4408,7 +4419,7 @@ NativeCodeProcedure::~NativeCodeProcedure(void)
|
|||
|
||||
}
|
||||
|
||||
void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc)
|
||||
void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
||||
{
|
||||
int nblocks = proc->mBlocks.Size();
|
||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||
|
@ -4427,9 +4438,9 @@ void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedu
|
|||
entryBlock->mNoFrame = mNoFrame;
|
||||
entryBlock->mIndex = 0;
|
||||
|
||||
generator->mByteCodeUsed[BC_NATIVE] = true;
|
||||
// generator->mByteCodeUsed[BC_NATIVE] = true;
|
||||
|
||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, BC_NATIVE * 2));
|
||||
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BYTE, ASMIM_IMPLIED, 0xea));
|
||||
|
||||
if (!mNoFrame)
|
||||
{
|
||||
|
@ -4564,21 +4575,18 @@ void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedu
|
|||
NativeCodeBasicBlock* lentryBlock = entryBlock->BypassEmptyBlocks();
|
||||
|
||||
total = 0;
|
||||
base = generator->mProgEnd;
|
||||
|
||||
lentryBlock->CalculateOffset(total);
|
||||
|
||||
generator->AddAddress(proc->mID, true, base, total, proc->mIdent, true);
|
||||
|
||||
lentryBlock->CopyCode(this, generator->mMemory + base);
|
||||
|
||||
generator->mProgEnd += total;
|
||||
proc->mLinkerObject->mType = LOT_NATIVE_CODE;
|
||||
lentryBlock->CopyCode(this, proc->mLinkerObject->AddSpace(total));
|
||||
|
||||
for (int i = 0; i < mRelocations.Size(); i++)
|
||||
{
|
||||
ByteCodeRelocation& rl(mRelocations[i]);
|
||||
rl.mAddr += base;
|
||||
generator->mRelocations.Push(rl);
|
||||
LinkerReference& rl(mRelocations[i]);
|
||||
rl.mObject = proc->mLinkerObject;
|
||||
if (!rl.mRefObject)
|
||||
rl.mRefObject = proc->mLinkerObject;
|
||||
mGenerator->mLinker->AddReference(rl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4670,7 +4678,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|||
iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
||||
iblock->mInstructions[i + 1]->mSTemp[0] == ins->mTTemp && iblock->mInstructions[i + 1]->mSFinal[0])
|
||||
{
|
||||
block->BinaryOperator(iproc, iblock->mInstructions[i + 1], nullptr, ins);
|
||||
block->BinaryOperator(iproc, this, iblock->mInstructions[i + 1], nullptr, ins);
|
||||
i++;
|
||||
}
|
||||
else if (i + 1 < iblock->mInstructions.Size() &&
|
||||
|
@ -4678,7 +4686,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|||
iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
||||
iblock->mInstructions[i + 1]->mSTemp[1] == ins->mTTemp && iblock->mInstructions[i + 1]->mSFinal[1])
|
||||
{
|
||||
block->BinaryOperator(iproc, iblock->mInstructions[i + 1], ins, nullptr);
|
||||
block->BinaryOperator(iproc, this, iblock->mInstructions[i + 1], ins, nullptr);
|
||||
i++;
|
||||
}
|
||||
else if (i + 2 < iblock->mInstructions.Size() &&
|
||||
|
@ -4688,7 +4696,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|||
iblock->mInstructions[i + 2]->mSTemp[0] == iblock->mInstructions[i + 1]->mTTemp && iblock->mInstructions[i + 2]->mSFinal[0] &&
|
||||
iblock->mInstructions[i + 2]->mSTemp[1] == ins->mTTemp && iblock->mInstructions[i + 2]->mSFinal[1])
|
||||
{
|
||||
block->BinaryOperator(iproc, iblock->mInstructions[i + 2], ins, iblock->mInstructions[i + 1]);
|
||||
block->BinaryOperator(iproc, this, iblock->mInstructions[i + 2], ins, iblock->mInstructions[i + 1]);
|
||||
i += 2;
|
||||
}
|
||||
else if (i + 2 < iblock->mInstructions.Size() &&
|
||||
|
@ -4698,7 +4706,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|||
iblock->mInstructions[i + 2]->mSTemp[1] == iblock->mInstructions[i + 1]->mTTemp && iblock->mInstructions[i + 2]->mSFinal[1] &&
|
||||
iblock->mInstructions[i + 2]->mSTemp[0] == ins->mTTemp && iblock->mInstructions[i + 2]->mSFinal[0])
|
||||
{
|
||||
block->BinaryOperator(iproc, iblock->mInstructions[i + 2], iblock->mInstructions[i + 1], ins);
|
||||
block->BinaryOperator(iproc, this, iblock->mInstructions[i + 2], iblock->mInstructions[i + 1], ins);
|
||||
i += 2;
|
||||
}
|
||||
else if (i + 1 < iblock->mInstructions.Size() &&
|
||||
|
@ -4733,13 +4741,13 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|||
}
|
||||
} break;
|
||||
case IC_BINARY_OPERATOR:
|
||||
block->BinaryOperator(iproc, ins, nullptr, nullptr);
|
||||
block->BinaryOperator(iproc, this, ins, nullptr, nullptr);
|
||||
break;
|
||||
case IC_UNARY_OPERATOR:
|
||||
block->UnaryOperator(iproc, ins);
|
||||
block->UnaryOperator(iproc, this, ins);
|
||||
break;
|
||||
case IC_CONVERSION_OPERATOR:
|
||||
block->NumericConversion(iproc, ins);
|
||||
block->NumericConversion(iproc, this, ins);
|
||||
break;
|
||||
case IC_LEA:
|
||||
block->LoadEffectiveAddress(iproc, ins, nullptr, nullptr);
|
||||
|
@ -4748,7 +4756,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|||
block->LoadConstant(iproc, ins);
|
||||
break;
|
||||
case IC_CALL:
|
||||
block->CallFunction(iproc, ins);
|
||||
block->CallFunction(iproc, this, ins);
|
||||
break;
|
||||
case IC_JSR:
|
||||
block->CallAssembler(iproc, ins);
|
||||
|
@ -4891,3 +4899,30 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
|||
block->Close(CompileBlock(iproc, iblock->mTrueJump), nullptr, ASMIT_JMP);
|
||||
}
|
||||
|
||||
|
||||
NativeCodeGenerator::NativeCodeGenerator(Errors* errors, Linker* linker)
|
||||
: mErrors(errors), mLinker(linker), mRuntime({ 0 })
|
||||
{
|
||||
}
|
||||
|
||||
NativeCodeGenerator::~NativeCodeGenerator(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NativeCodeGenerator::Runtime& NativeCodeGenerator::ResolveRuntime(const Ident* ident)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < mRuntime.Size() && mRuntime[i].mIdent != ident)
|
||||
i++;
|
||||
return mRuntime[i];
|
||||
}
|
||||
|
||||
void NativeCodeGenerator::RegisterRuntime(const Ident* ident, LinkerObject* object, int offset)
|
||||
{
|
||||
Runtime rt;
|
||||
rt.mIdent = ident;
|
||||
rt.mLinkerObject = object;
|
||||
rt.mOffset = offset;
|
||||
mRuntime.Push(rt);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "ByteCodeGenerator.h"
|
||||
#include "Assembler.h"
|
||||
#include "Linker.h"
|
||||
#include "InterCode.h"
|
||||
|
||||
class NativeCodeProcedure;
|
||||
class NativeCodeBasicBlock;
|
||||
class NativeCodeGenerator;
|
||||
|
||||
struct NativeRegisterData
|
||||
{
|
||||
|
@ -24,20 +26,22 @@ struct NativeRegisterDataSet
|
|||
void ResetZeroPage(int addr);
|
||||
};
|
||||
|
||||
static const uint32 NCIF_LOWER = 0x00000001;
|
||||
static const uint32 NCIF_UPPER = 0x00000002;
|
||||
static const uint32 NCIF_RUNTIME = 0x00000004;
|
||||
|
||||
class NativeCodeInstruction
|
||||
{
|
||||
public:
|
||||
NativeCodeInstruction(AsmInsType type = ASMIT_INV, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, int varIndex = -1, bool lower = true, bool upper = true);
|
||||
NativeCodeInstruction(AsmInsType type, AsmInsMode mode, const char* runtime, int address = 0, bool lower = true, bool upper = true);
|
||||
NativeCodeInstruction(const char* runtime);
|
||||
NativeCodeInstruction(AsmInsType type = ASMIT_INV, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER);
|
||||
|
||||
AsmInsType mType;
|
||||
AsmInsMode mMode;
|
||||
|
||||
int mAddress, mVarIndex;
|
||||
bool mLower, mUpper, mFunction;
|
||||
const char * mRuntime;
|
||||
int mAddress;
|
||||
uint32 mFlags;
|
||||
uint32 mLive;
|
||||
LinkerObject* mLinkerObject;
|
||||
|
||||
void Assemble(NativeCodeBasicBlock* block);
|
||||
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||
|
@ -63,7 +67,7 @@ public:
|
|||
AsmInsType mBranch;
|
||||
|
||||
GrowingArray<NativeCodeInstruction> mIns;
|
||||
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||
GrowingArray<LinkerReference> mRelocations;
|
||||
|
||||
int mOffset, mSize, mNumEntries;
|
||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited;
|
||||
|
@ -91,18 +95,18 @@ public:
|
|||
void StoreValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
void LoadValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
void LoadStoreValue(InterCodeProcedure* proc, const InterInstruction * rins, const InterInstruction * wins);
|
||||
void BinaryOperator(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
|
||||
void UnaryOperator(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
void BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
|
||||
void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
|
||||
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
|
||||
void NumericConversion(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
void NumericConversion(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
void CopyValue(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure* nproc);
|
||||
|
||||
void CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
void CallFunction(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||
|
||||
void ShiftRegisterLeft(InterCodeProcedure* proc, int reg, int shift);
|
||||
int ShortMultiply(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins, int index, int mul);
|
||||
int ShortMultiply(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins, int index, int mul);
|
||||
|
||||
bool CheckPredAccuStore(int reg);
|
||||
|
||||
|
@ -124,20 +128,22 @@ public:
|
|||
class NativeCodeProcedure
|
||||
{
|
||||
public:
|
||||
NativeCodeProcedure(void);
|
||||
NativeCodeProcedure(NativeCodeGenerator* generator);
|
||||
~NativeCodeProcedure(void);
|
||||
|
||||
NativeCodeBasicBlock* entryBlock, * exitBlock;
|
||||
NativeCodeBasicBlock** tblocks;
|
||||
|
||||
NativeCodeGenerator* mGenerator;
|
||||
|
||||
int mProgStart, mProgSize, mIndex;
|
||||
bool mNoFrame;
|
||||
int mTempBlocks;
|
||||
|
||||
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||
GrowingArray<LinkerReference> mRelocations;
|
||||
GrowingArray < NativeCodeBasicBlock*> mBlocks;
|
||||
|
||||
void Compile( ByteCodeGenerator * generator, InterCodeProcedure* proc);
|
||||
void Compile(InterCodeProcedure* proc);
|
||||
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
||||
NativeCodeBasicBlock* AllocateBlock(void);
|
||||
NativeCodeBasicBlock* TransientBlock(void);
|
||||
|
@ -149,3 +155,24 @@ class NativeCodeProcedure
|
|||
|
||||
};
|
||||
|
||||
class NativeCodeGenerator
|
||||
{
|
||||
public:
|
||||
NativeCodeGenerator(Errors * errors, Linker* linker);
|
||||
~NativeCodeGenerator(void);
|
||||
|
||||
void RegisterRuntime(const Ident * ident, LinkerObject * object, int offset);
|
||||
|
||||
struct Runtime
|
||||
{
|
||||
const Ident * mIdent;
|
||||
LinkerObject * mLinkerObject;
|
||||
int mOffset;
|
||||
};
|
||||
|
||||
Runtime& ResolveRuntime(const Ident* ident);
|
||||
|
||||
Errors* mErrors;
|
||||
Linker* mLinker;
|
||||
GrowingArray<Runtime> mRuntime;
|
||||
};
|
|
@ -235,7 +235,7 @@ int FastNumberSet::Index(int elem)
|
|||
{
|
||||
uint32 dw = buffer[size + elem];
|
||||
|
||||
if (dw < num && buffer[dw] == elem)
|
||||
if (dw < uint32(num) && buffer[dw] == elem)
|
||||
return dw;
|
||||
else
|
||||
return -1;
|
||||
|
|
|
@ -61,7 +61,7 @@ __forceinline bool NumberSet::operator[](int elem) const
|
|||
class FastNumberSet
|
||||
{
|
||||
protected:
|
||||
uint32 * buffer;
|
||||
uint32 * buffer;
|
||||
int size, num, asize;
|
||||
public:
|
||||
FastNumberSet(void);
|
||||
|
@ -92,14 +92,14 @@ __forceinline bool FastNumberSet::operator[](int elem)
|
|||
{
|
||||
uint32 dw = buffer[size + elem];
|
||||
|
||||
return (dw < num && buffer[dw] == elem);
|
||||
return (dw < uint32(num) && buffer[dw] == elem);
|
||||
}
|
||||
|
||||
__forceinline FastNumberSet& FastNumberSet::operator+=(int elem)
|
||||
{
|
||||
uint32 dw = buffer[size + elem];
|
||||
|
||||
if (dw >= num || buffer[dw] != elem)
|
||||
if (dw >= uint32(num) || buffer[dw] != elem)
|
||||
{
|
||||
buffer[num] = elem;
|
||||
buffer[size + elem] = num;
|
||||
|
@ -113,7 +113,7 @@ __forceinline FastNumberSet& FastNumberSet::operator-=(int elem)
|
|||
{
|
||||
uint32 dw = buffer[size + elem];
|
||||
|
||||
if (dw < num && buffer[dw] == elem)
|
||||
if (dw < uint32(num) && buffer[dw] == elem)
|
||||
{
|
||||
num--;
|
||||
buffer[dw] = buffer[num];
|
||||
|
|
|
@ -8,6 +8,9 @@ Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUn
|
|||
{
|
||||
mGlobals = new DeclarationScope(compilationUnits->mScope);
|
||||
mScope = mGlobals;
|
||||
|
||||
mCodeSection = Ident::Unique("code");
|
||||
mDataSection = Ident::Unique("code");
|
||||
}
|
||||
|
||||
Parser::~Parser(void)
|
||||
|
@ -263,7 +266,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
|||
mScanner->NextToken();
|
||||
Expression* exp = ParseRExpression();
|
||||
if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||
nitem = exp->mDecValue->mInteger;
|
||||
nitem = int(exp->mDecValue->mInteger);
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, "Integer constant expected");
|
||||
}
|
||||
|
@ -337,6 +340,7 @@ Declaration* Parser::ParsePostfixDeclaration(void)
|
|||
{
|
||||
dec = new Declaration(mScanner->mLocation, DT_VARIABLE);
|
||||
dec->mIdent = mScanner->mTokenIdent;
|
||||
dec->mSection = mDataSection;
|
||||
dec->mBase = nullptr;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
|
@ -358,7 +362,7 @@ Declaration* Parser::ParsePostfixDeclaration(void)
|
|||
{
|
||||
Expression* exp = ParseRExpression();
|
||||
if (exp->mType == EX_CONSTANT && exp->mDecType->IsIntegerType() && exp->mDecValue->mType == DT_CONST_INTEGER)
|
||||
ndec->mSize = exp->mDecValue->mInteger;
|
||||
ndec->mSize = int(exp->mDecValue->mInteger);
|
||||
else
|
||||
mErrors->Error(exp->mLocation, "Constant integer expression expected");
|
||||
ndec->mFlags |= DTF_DEFINED;
|
||||
|
@ -488,7 +492,7 @@ Declaration * Parser::CopyConstantInitializer(int offset, Declaration* dtype, Ex
|
|||
if (dtype->mType == DT_TYPE_FLOAT)
|
||||
{
|
||||
Declaration* ndec = new Declaration(dec->mLocation, DT_CONST_FLOAT);
|
||||
ndec->mNumber = dec->mInteger;
|
||||
ndec->mNumber = double(dec->mInteger);
|
||||
ndec->mBase = dtype;
|
||||
dec = ndec;
|
||||
}
|
||||
|
@ -512,6 +516,7 @@ Declaration * Parser::CopyConstantInitializer(int offset, Declaration* dtype, Ex
|
|||
else
|
||||
{
|
||||
Declaration* ndec = new Declaration(dec->mLocation, DT_CONST_DATA);
|
||||
ndec->mSection = dec->mSection;
|
||||
ndec->mData = dec->mData;
|
||||
ndec->mSize = dec->mSize;
|
||||
ndec->mBase = dtype;
|
||||
|
@ -547,6 +552,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
|||
dec = new Declaration(mScanner->mLocation, DT_CONST_STRUCT);
|
||||
dec->mBase = dtype;
|
||||
dec->mSize = dtype->mSize;
|
||||
dec->mSection = mDataSection;
|
||||
|
||||
Declaration* last = nullptr;
|
||||
|
||||
|
@ -617,6 +623,8 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
|||
dec = new Declaration(mScanner->mLocation, DT_CONST_DATA);
|
||||
dec->mBase = dtype;
|
||||
dec->mSize = dtype->mSize;
|
||||
dec->mSection = mDataSection;
|
||||
|
||||
uint8* d = new uint8[dtype->mSize];
|
||||
dec->mData = d;
|
||||
|
||||
|
@ -710,7 +718,10 @@ Declaration* Parser::ParseDeclaration(bool variable)
|
|||
ndec->mFlags |= ndec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
|
||||
|
||||
if (ndec->mBase->mType == DT_TYPE_FUNCTION)
|
||||
{
|
||||
ndec->mType = DT_CONST_FUNCTION;
|
||||
ndec->mSection = mCodeSection;
|
||||
}
|
||||
|
||||
if (ndec->mIdent)
|
||||
{
|
||||
|
@ -903,6 +914,7 @@ Expression* Parser::ParseSimpleExpression(void)
|
|||
dec = new Declaration(mScanner->mLocation, DT_CONST_DATA);
|
||||
dec->mSize = strlen(mScanner->mTokenString) + 1;
|
||||
dec->mVarIndex = -1;
|
||||
dec->mSection = mCodeSection;
|
||||
dec->mBase = new Declaration(mScanner->mLocation, DT_TYPE_ARRAY);
|
||||
dec->mBase->mSize = dec->mSize;
|
||||
dec->mBase->mBase = TheConstCharTypeDeclaration;
|
||||
|
@ -1877,23 +1889,51 @@ Expression* Parser::ParseAssemblerBaseOperand(void)
|
|||
return exp;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseAssemblerAddOperand(void)
|
||||
Expression* Parser::ParseAssemblerMulOperand(void)
|
||||
{
|
||||
Expression* exp = ParseAssemblerBaseOperand();
|
||||
while (mScanner->mToken == TK_ADD || mScanner->mToken == TK_SUB)
|
||||
while (mScanner->mToken == TK_MUL || mScanner->mToken == TK_DIV || mScanner->mToken == TK_MOD)
|
||||
{
|
||||
Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY);
|
||||
nexp->mToken = mScanner->mToken;
|
||||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseAssemblerBaseOperand();
|
||||
exp = nexp->ConstantFold();
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseAssemblerAddOperand(void)
|
||||
{
|
||||
Expression* exp = ParseAssemblerMulOperand();
|
||||
while (mScanner->mToken == TK_ADD || mScanner->mToken == TK_SUB)
|
||||
{
|
||||
Expression* nexp = new Expression(mScanner->mLocation, EX_BINARY);
|
||||
nexp->mToken = mScanner->mToken;
|
||||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseAssemblerMulOperand();
|
||||
if (nexp->mLeft->mDecValue->mType == DT_VARIABLE)
|
||||
{
|
||||
if (nexp->mRight->mDecValue->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_VARIABLE_REF);
|
||||
ndec->mBase = nexp->mLeft->mDecValue;
|
||||
ndec->mOffset = nexp->mRight->mDecValue->mInteger;
|
||||
ndec->mOffset = int(nexp->mRight->mDecValue->mInteger);
|
||||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, "Integer offset expected");
|
||||
}
|
||||
else if (nexp->mLeft->mDecValue->mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
if (nexp->mRight->mDecValue->mType == DT_CONST_INTEGER)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_FUNCTION_REF);
|
||||
ndec->mBase = nexp->mLeft->mDecValue;
|
||||
ndec->mOffset = int(nexp->mRight->mDecValue->mInteger);
|
||||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
|
@ -1906,7 +1946,7 @@ Expression* Parser::ParseAssemblerAddOperand(void)
|
|||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_LABEL_REF);
|
||||
ndec->mBase = nexp->mLeft->mDecValue;
|
||||
ndec->mOffset = nexp->mRight->mDecValue->mInteger;
|
||||
ndec->mOffset = int(nexp->mRight->mDecValue->mInteger);
|
||||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
|
@ -1951,6 +1991,38 @@ Expression* Parser::ParseAssemblerOperand(void)
|
|||
ndec->mFlags |= DTF_LOWER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else if (exp->mDecValue->mType == DT_VARIABLE)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_VARIABLE_REF);
|
||||
ndec->mBase = exp->mDecValue;
|
||||
ndec->mOffset = 0;
|
||||
ndec->mFlags |= DTF_LOWER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else if (exp->mDecValue->mType == DT_VARIABLE_REF)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_VARIABLE_REF);
|
||||
ndec->mBase = exp->mDecValue->mBase;
|
||||
ndec->mOffset = exp->mDecValue->mOffset;
|
||||
ndec->mFlags |= DTF_LOWER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else if (exp->mDecValue->mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_FUNCTION_REF);
|
||||
ndec->mBase = exp->mDecValue;
|
||||
ndec->mOffset = 0;
|
||||
ndec->mFlags |= DTF_LOWER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else if (exp->mDecValue->mType == DT_FUNCTION_REF)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_FUNCTION_REF);
|
||||
ndec->mBase = exp->mDecValue->mBase;
|
||||
ndec->mOffset = exp->mDecValue->mOffset;
|
||||
ndec->mFlags |= DTF_LOWER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, "Label or integer value for lower byte operator expected");
|
||||
}
|
||||
|
@ -1989,6 +2061,38 @@ Expression* Parser::ParseAssemblerOperand(void)
|
|||
ndec->mFlags |= DTF_UPPER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else if (exp->mDecValue->mType == DT_VARIABLE)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_VARIABLE_REF);
|
||||
ndec->mBase = exp->mDecValue;
|
||||
ndec->mOffset = 0;
|
||||
ndec->mFlags |= DTF_UPPER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else if (exp->mDecValue->mType == DT_VARIABLE_REF)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_VARIABLE_REF);
|
||||
ndec->mBase = exp->mDecValue->mBase;
|
||||
ndec->mOffset = exp->mDecValue->mOffset;
|
||||
ndec->mFlags |= DTF_UPPER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else if (exp->mDecValue->mType == DT_CONST_FUNCTION)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_FUNCTION_REF);
|
||||
ndec->mBase = exp->mDecValue;
|
||||
ndec->mOffset = 0;
|
||||
ndec->mFlags |= DTF_UPPER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else if (exp->mDecValue->mType == DT_FUNCTION_REF)
|
||||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_FUNCTION_REF);
|
||||
ndec->mBase = exp->mDecValue->mBase;
|
||||
ndec->mOffset = exp->mDecValue->mOffset;
|
||||
ndec->mFlags |= DTF_UPPER_BYTE;
|
||||
exp->mDecValue = ndec;
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, "Label or integer value for lower byte operator expected");
|
||||
}
|
||||
|
@ -2027,6 +2131,7 @@ Expression* Parser::ParseAssembler(void)
|
|||
|
||||
Declaration* vdasm = new Declaration(mScanner->mLocation, DT_CONST_ASSEMBLER);
|
||||
vdasm->mVarIndex = -1;
|
||||
vdasm->mSection = mCodeSection;
|
||||
|
||||
vdasm->mBase = dassm;
|
||||
|
||||
|
@ -2159,6 +2264,9 @@ Expression* Parser::ParseAssembler(void)
|
|||
ilast->mAsmInsMode = ASMIM_ZERO_PAGE_Y;
|
||||
}
|
||||
|
||||
if (ilast->mAsmInsType == ASMIT_BYTE)
|
||||
ilast->mAsmInsMode = ASMIM_IMMEDIATE;
|
||||
|
||||
if (mScanner->mToken != TK_EOL)
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, "End of line expected");
|
||||
|
|
|
@ -14,6 +14,8 @@ public:
|
|||
int mLocalIndex;
|
||||
CompilationUnits * mCompilationUnits;
|
||||
|
||||
const Ident* mCodeSection, * mDataSection;
|
||||
|
||||
void Parse(void);
|
||||
protected:
|
||||
bool ConsumeToken(Token token);
|
||||
|
@ -36,6 +38,7 @@ protected:
|
|||
Expression* ParseAssembler(void);
|
||||
|
||||
Expression* ParseAssemblerBaseOperand(void);
|
||||
Expression* ParseAssemblerMulOperand(void);
|
||||
Expression* ParseAssemblerAddOperand(void);
|
||||
Expression* ParseAssemblerOperand(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue