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