Using linker objects and sections

This commit is contained in:
drmortalwombat 2021-09-20 22:36:16 +02:00
parent 78886f11f7
commit 27d7baaac2
22 changed files with 995 additions and 1246 deletions

View File

@ -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)

View File

@ -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;
}

View File

@ -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);
}; };

View File

@ -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);

View File

@ -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);
}; };

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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);
}; };

View File

@ -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];

View File

@ -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)
{ {
} }

View File

@ -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);
}; };

View File

@ -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;

View File

@ -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);
}; };

View File

@ -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;
}
} }
} }

View File

@ -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;
}; };

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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];

View File

@ -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");

View File

@ -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);