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