Using linker objects and sections

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

View File

@ -1,15 +1,28 @@
// crt.c
#include <crt.h>
unsigned int CodeStart = 0x0a00;
unsigned int StackTop = 0xa000 - 2;
int main(void);
__asm startup
{
lda CodeStart + 0
byt 0x0b
byt 0x08
byt 0x0a
byt 0x00
byt 0x9e
byt 0x32
byt 0x30
byt 0x36
byt 0x31
byt 0x00
byt 0x00
byt 0x00
lda #<bcode
sta ip
lda CodeStart + 1
lda #>bcode
sta ip + 1
lda StackTop + 0
@ -34,6 +47,13 @@ incip:
bcc execjmp
inc ip + 1
bne execjmp
bcode:
byt BC_LEA_ABS * 2
byt addr
byt <main
byt >main
byt BC_CALL * 2
byt BC_EXIT * 2
}
#pragma startup(startup)

View File

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

View File

@ -153,15 +153,6 @@ enum ByteCode
class ByteCodeProcedure;
class ByteCodeGenerator;
class ByteCodeRelocation
{
public:
uint16 mAddr;
bool mFunction, mLower, mUpper;
uint16 mIndex, mOffset;
const char * mRuntime;
};
class ByteCodeBasicBlock;
class ByteCodeInstruction
@ -173,8 +164,9 @@ public:
ByteCode mCode;
uint32 mRegister;
int mValue, mVIndex;
bool mRelocate, mFunction, mRegisterFinal;
int mValue;
bool mRelocate, mRegisterFinal;
LinkerObject* mLinkerObject;
bool IsStore(void) const;
bool ChangesAccu(void) const;
@ -197,7 +189,7 @@ public:
ByteCode mBranch;
GrowingArray<ByteCodeInstruction> mIns;
GrowingArray<ByteCodeRelocation> mRelocations;
GrowingArray<LinkerReference> mRelocations;
int mOffset, mSize;
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled;
@ -218,7 +210,7 @@ public:
ByteCodeBasicBlock* BypassEmptyBlocks(void);
void CalculateOffset(int& total);
void CopyCode(ByteCodeGenerator* generator, uint8* target);
void CopyCode(ByteCodeGenerator* generator, LinkerObject * linkerObject, uint8* target);
void IntConstToAccu(__int64 val);
void IntConstToAddr(__int64 val);
@ -252,12 +244,11 @@ public:
ByteCodeBasicBlock * entryBlock, * exitBlock;
ByteCodeBasicBlock ** tblocks;
int mProgStart, mProgSize, mID;
int mProgSize, mID;
void Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc);
ByteCodeBasicBlock * CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
void Disassemble(FILE * file, ByteCodeGenerator* generator, InterCodeProcedure* proc);
protected:
ByteCodeDisassembler mDisassembler;
};
@ -265,39 +256,15 @@ protected:
class ByteCodeGenerator
{
public:
ByteCodeGenerator(void);
ByteCodeGenerator(Errors* errors, Linker* linker);
~ByteCodeGenerator(void);
struct Address
{
int mIndex, mAddress, mSize;
bool mFunction, mAssembler;
const Ident* mIdent;
};
GrowingArray<Address> mProcedureAddr, mGlobalAddr;
GrowingArray<ByteCodeRelocation> mRelocations;
Errors* mErrors;
Linker* mLinker;
bool mByteCodeUsed[128];
uint8 mMemory[0x10000];
int mProgEnd, mProgStart, mProgEntry;
void WriteBasicHeader(void);
void WriteByteCodeHeader(void);
void SetBasicEntry(int index);
bool WritePRGFile(const char* filename);
bool WriteMapFile(const char* filename);
void WriteAsmFile(FILE * file);
void WriteAsmFile(FILE* file, Address & addr);
void ResolveRelocations(void);
int AddGlobal(int index, const Ident* ident, int size, const uint8* data, bool assembler);
void AddAddress(int index, bool function, int address, int size, const Ident * ident, bool assembler);
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +1,11 @@
#pragma once
#include <stdio.h>
#include "InterCode.h"
#include "MachineTypes.h"
#include "Ident.h"
class ByteCodeGenerator;
class InterCodeProcedure;
class ByteCodeDisassembler
{
@ -11,7 +13,7 @@ public:
ByteCodeDisassembler(void);
~ByteCodeDisassembler(void);
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc);
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident);
protected:
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc);
};
@ -22,7 +24,7 @@ public:
NativeCodeDisassembler(void);
~NativeCodeDisassembler(void);
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc);
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident);
protected:
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc);
};

View File

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

View File

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

View File

@ -7,6 +7,7 @@
#include <stdio.h>
#include "MachineTypes.h"
#include "Ident.h"
#include "Linker.h"
enum InterCode
{
@ -119,7 +120,7 @@ typedef GrowingArray<InterInstruction *> GrowingInstructionArray;
typedef GrowingArray<InterCodeProcedurePtr > GrowingInterCodeProcedurePtrArray;
typedef GrowingArray<InterVariable> GrowingVariableArray;
typedef GrowingArray<InterVariable * > GrowingVariableArray;
#define INVALID_TEMPORARY (-1)
@ -269,28 +270,20 @@ public:
class InterVariable
{
public:
bool mUsed, mAliased, mPlaced, mAssembler;
int mIndex, mSize, mOffset, mAddr;
int mNumReferences;
const uint8 * mData;
const Ident * mIdent;
struct Reference
{
uint16 mAddr;
bool mFunction, mLower, mUpper;
uint16 mIndex, mOffset;
} *mReferences;
Location mLocation;
bool mUsed, mAliased;
int mIndex, mSize, mOffset, mAddr;
int mNumReferences;
const Ident * mIdent;
LinkerObject * mLinkerObject;
InterVariable(void)
: mUsed(false), mAliased(false), mPlaced(false), mIndex(-1), mSize(0), mOffset(0), mNumReferences(0), mData(nullptr), mIdent(nullptr), mReferences(nullptr), mAssembler(false)
: mUsed(false), mAliased(false), mIndex(-1), mSize(0), mOffset(0), mIdent(nullptr), mLinkerObject(nullptr)
{
}
};
typedef GrowingArray<InterVariable::Reference> GrowingInterVariableReferenceArray;
class InterInstruction
{
public:
@ -307,6 +300,7 @@ public:
__int64 mIntValue;
double mFloatValue;
Location mLocation;
LinkerObject * mLinkerObject;
bool mInUse;
@ -497,9 +491,11 @@ public:
GrowingVariableArray mLocalVars;
Location mLocation;
const Ident * mIdent;
const Ident * mIdent, * mSection;
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident);
LinkerObject * mLinkerObject;
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);
~InterCodeProcedure(void);
int AddTemporary(InterType type);
@ -532,6 +528,4 @@ public:
GrowingInterCodeProcedurePtrArray mProcedures;
GrowingVariableArray mGlobalVars;
void UseGlobal(int index);
};

View File

@ -1,8 +1,8 @@
#include "InterCodeGenerator.h"
#include <crtdbg.h>
InterCodeGenerator::InterCodeGenerator(Errors* errors)
: mErrors(errors), mForceNativeCode(false)
InterCodeGenerator::InterCodeGenerator(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker), mForceNativeCode(false)
{
}
@ -182,37 +182,30 @@ static inline InterType InterTypeOfArithmetic(InterType t1, InterType t2)
void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* dec)
{
if (dec->mVarIndex < 0)
if (!dec->mLinkerObject)
{
InterVariable var;
var.mOffset = 0;
var.mSize = dec->mSize;
var.mData = nullptr;
var.mIdent = dec->mIdent;
InterVariable * var = new InterVariable();
var->mOffset = 0;
var->mSize = dec->mSize;
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
var->mIdent = dec->mIdent;
var->mIndex = mod->mGlobalVars.Size();
mod->mGlobalVars.Push(var);
dec->mVarIndex = var->mIndex;
dec->mLinkerObject = var->mLinkerObject;
uint8* d = var->mLinkerObject->AddSpace(var->mSize);
if (dec->mValue)
{
if (dec->mValue->mType == EX_CONSTANT)
{
uint8* d = new uint8[dec->mSize];
memset(d, 0, dec->mSize);
var.mData = d;
GrowingArray<InterVariable::Reference> references({ 0 });
BuildInitializer(mod, d, 0, dec->mValue->mDecValue, references);
var.mNumReferences = references.Size();
if (var.mNumReferences)
{
var.mReferences = new InterVariable::Reference[var.mNumReferences];
for (int i = 0; i < var.mNumReferences; i++)
var.mReferences[i] = references[i];
}
{
BuildInitializer(mod, d, 0, dec->mValue->mDecValue, var);
}
else
mErrors->Error(dec->mLocation, "Non constant initializer");
}
dec->mVarIndex = mod->mGlobalVars.Size();
var.mIndex = dec->mVarIndex;
mod->mGlobalVars.Push(var);
}
}
@ -226,22 +219,11 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
cexp = cexp->mRight;
}
InterVariable var;
var.mOffset = 0;
var.mSize = osize;
uint8* d = new uint8[osize];
var.mData = d;
var.mAssembler = true;
Declaration* dec = exp->mDecValue;
var.mIndex = mod->mGlobalVars.Size();
if (exp->mDecValue)
{
exp->mDecValue->mVarIndex = var.mIndex;
var.mIdent = exp->mDecValue->mIdent;
}
mod->mGlobalVars.Push(var);
dec->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_NATIVE_CODE);
GrowingArray<InterVariable::Reference> references({ 0 });
uint8* d = dec->mLinkerObject->AddSpace(osize);
cexp = exp;
while (cexp)
@ -265,18 +247,36 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
d[offset++] = cexp->mLeft->mDecValue->mInteger & 255;
else if (aexp->mType == DT_LABEL_REF)
{
if (aexp->mBase->mBase->mVarIndex < 0)
if (!aexp->mBase->mBase->mLinkerObject)
TranslateAssembler(mod, aexp->mBase->mBase->mValue);
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = aexp->mFlags & DTF_UPPER_BYTE;
ref.mLower = !(aexp->mFlags & DTF_UPPER_BYTE);
ref.mAddr = offset;
ref.mIndex = aexp->mBase->mBase->mVarIndex;
ref.mOffset = aexp->mOffset + aexp->mBase->mInteger;
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = aexp->mFlags & DTF_UPPER_BYTE;
ref.mLowByte = !(aexp->mFlags & DTF_UPPER_BYTE);
ref.mRefObject = aexp->mBase->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset + aexp->mBase->mInteger;
mLinker->AddReference(ref);
references.Push(ref);
offset += 1;
}
else if (aexp->mType == DT_FUNCTION_REF)
{
if (!aexp->mBase->mLinkerObject)
{
InterCodeProcedure* cproc = this->TranslateProcedure(mod, aexp->mBase->mValue, aexp->mBase);
cproc->ReduceTemporaries();
}
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = aexp->mFlags & DTF_UPPER_BYTE;
ref.mLowByte = !(aexp->mFlags & DTF_UPPER_BYTE);
ref.mRefObject = aexp->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset;
mLinker->AddReference(ref);
offset += 1;
}
@ -298,52 +298,49 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
}
else if (aexp->mType == DT_LABEL)
{
if (aexp->mBase->mVarIndex < 0)
if (!aexp->mBase->mLinkerObject)
TranslateAssembler(mod, aexp->mBase->mValue);
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = true;
ref.mLower = true;
ref.mAddr = offset;
ref.mIndex = aexp->mBase->mVarIndex;
ref.mOffset = aexp->mInteger;
references.Push(ref);
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mRefObject = aexp->mBase->mLinkerObject;
ref.mRefOffset = aexp->mInteger;
mLinker->AddReference(ref);
offset += 2;
}
else if (aexp->mType == DT_LABEL_REF)
{
if (aexp->mBase->mBase->mVarIndex < 0)
if (!aexp->mBase->mBase->mLinkerObject)
TranslateAssembler(mod, aexp->mBase->mBase->mValue);
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = true;
ref.mLower = true;
ref.mAddr = offset;
ref.mIndex = aexp->mBase->mBase->mVarIndex;
ref.mOffset = aexp->mOffset + aexp->mBase->mInteger;
references.Push(ref);
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mRefObject = aexp->mBase->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset + aexp->mBase->mInteger;
mLinker->AddReference(ref);
offset += 2;
}
else if (aexp->mType == DT_CONST_ASSEMBLER)
{
if (aexp->mVarIndex < 0)
if (!aexp->mLinkerObject)
TranslateAssembler(mod, aexp->mValue);
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = true;
ref.mLower = true;
ref.mAddr = offset;
ref.mIndex = aexp->mVarIndex;
ref.mOffset = 0;
references.Push(ref);
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mRefObject = aexp->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
offset += 2;
}
@ -353,15 +350,14 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
{
InitGlobalVariable(mod, aexp);
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = true;
ref.mLower = true;
ref.mAddr = offset;
ref.mIndex = aexp->mVarIndex;
ref.mOffset = 0;
references.Push(ref);
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mRefObject = aexp->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
offset += 2;
}
@ -372,19 +368,56 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
{
InitGlobalVariable(mod, aexp->mBase);
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = true;
ref.mLower = true;
ref.mAddr = offset;
ref.mIndex = aexp->mBase->mVarIndex;
ref.mOffset = aexp->mOffset;
references.Push(ref);
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mRefObject = aexp->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset;
mLinker->AddReference(ref);
offset += 2;
}
}
else if (aexp->mType == DT_CONST_FUNCTION)
{
if (!aexp->mLinkerObject)
{
InterCodeProcedure* cproc = this->TranslateProcedure(mod, aexp->mValue, aexp);
cproc->ReduceTemporaries();
}
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mRefObject = aexp->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
offset += 2;
}
else if (aexp->mType == DT_FUNCTION_REF)
{
if (!aexp->mBase->mLinkerObject)
{
InterCodeProcedure* cproc = this->TranslateProcedure(mod, aexp->mBase->mValue, aexp->mBase);
cproc->ReduceTemporaries();
}
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mRefObject = aexp->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset;
mLinker->AddReference(ref);
offset += 2;
}
break;
case ASMIM_RELATIVE:
d[offset] = aexp->mInteger - offset - 1;
@ -396,16 +429,6 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
}
assert(offset == osize);
InterVariable& ivar(mod->mGlobalVars[var.mIndex]);
ivar.mNumReferences = references.Size();
if (ivar.mNumReferences)
{
ivar.mReferences = new InterVariable::Reference[ivar.mNumReferences];
for (int i = 0; i < ivar.mNumReferences; i++)
ivar.mReferences[i] = references[i];
}
}
InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock)
@ -500,7 +523,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case DT_CONST_FUNCTION:
{
if (dec->mVarIndex < 0)
if (!dec->mLinkerObject)
{
InterCodeProcedure* cproc = this->TranslateProcedure(proc->mModule, dec->mValue, dec);
cproc->ReduceTemporaries();
@ -511,6 +534,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mTType = InterTypeOf(dec->mBase);
ins->mTTemp = proc->AddTemporary(ins->mTType);
ins->mVarIndex = dec->mVarIndex;
ins->mLinkerObject = dec->mLinkerObject;
ins->mMemory = IM_PROCEDURE;
ins->mIntValue = 0;
block->Append(ins);
@ -525,15 +549,17 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
}
case DT_CONST_DATA:
{
if (dec->mVarIndex < 0)
if (!dec->mLinkerObject)
{
dec->mVarIndex = proc->mModule->mGlobalVars.Size();
InterVariable var;
var.mIndex = dec->mVarIndex;
var.mIdent = dec->mIdent;
var.mOffset = 0;
var.mSize = dec->mSize;
var.mData = dec->mData;
InterVariable* var = new InterVariable();
var->mIndex = dec->mVarIndex;
var->mIdent = dec->mIdent;
var->mOffset = 0;
var->mSize = dec->mSize;
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
dec->mLinkerObject = var->mLinkerObject;
var->mLinkerObject->AddData(dec->mData, dec->mSize);
proc->mModule->mGlobalVars.Push(var);
}
@ -543,6 +569,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mTTemp = proc->AddTemporary(IT_POINTER);
ins->mIntValue = 0;
ins->mVarIndex = dec->mVarIndex;
ins->mLinkerObject = dec->mLinkerObject;
ins->mMemory = IM_GLOBAL;
block->Append(ins);
return ExValue(dec->mBase, ins->mTTemp, 1);
@ -550,31 +577,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case DT_CONST_STRUCT:
{
if (dec->mVarIndex < 0)
if (!dec->mLinkerObject)
{
InterVariable var;
var.mOffset = 0;
var.mSize = dec->mSize;
var.mData = nullptr;
var.mIdent = dec->mIdent;
uint8* d = new uint8[dec->mSize];
memset(d, 0, dec->mSize);
var.mData = d;
GrowingArray<InterVariable::Reference> references({ 0 });
BuildInitializer(proc->mModule, d, 0, dec, references);
var.mNumReferences = references.Size();
if (var.mNumReferences)
{
var.mReferences = new InterVariable::Reference[var.mNumReferences];
for (int i = 0; i < var.mNumReferences; i++)
var.mReferences[i] = references[i];
}
InterVariable * var = new InterVariable();
var->mOffset = 0;
var->mSize = dec->mSize;
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
dec->mLinkerObject = var->mLinkerObject;
var->mIdent = dec->mIdent;
dec->mVarIndex = proc->mModule->mGlobalVars.Size();
var.mIndex = dec->mVarIndex;
var->mIndex = dec->mVarIndex;
proc->mModule->mGlobalVars.Push(var);
uint8* d = var->mLinkerObject->AddSpace(dec->mSize);;
BuildInitializer(proc->mModule, d, 0, dec, var);
}
InterInstruction * ins = new InterInstruction();
@ -583,6 +600,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mTTemp = proc->AddTemporary(IT_POINTER);
ins->mIntValue = 0;
ins->mVarIndex = dec->mVarIndex;
ins->mLinkerObject = dec->mLinkerObject;
ins->mMemory = IM_GLOBAL;
block->Append(ins);
return ExValue(dec->mBase, ins->mTTemp, 1);
@ -610,6 +628,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{
InitGlobalVariable(proc->mModule, dec);
ins->mMemory = IM_GLOBAL;
ins->mLinkerObject = dec->mLinkerObject;
}
else
ins->mMemory = IM_LOCAL;
@ -1531,202 +1550,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case EX_ASSEMBLER:
{
int offset = 0, osize = 0;
Expression* cexp = exp;
while (cexp)
{
osize += AsmInsSize(cexp->mAsmInsType, cexp->mAsmInsMode);
cexp = cexp->mRight;
}
TranslateAssembler(proc->mModule, exp);
InterInstruction * ins = new InterInstruction();
ins->mCode = IC_CONSTANT;
ins->mTType = IT_POINTER;
ins->mTTemp = proc->AddTemporary(ins->mTType);
ins->mOperandSize = osize;
ins->mIntValue = 0;
InterVariable var;
var.mOffset = 0;
var.mSize = osize;
uint8* d = new uint8[osize];
var.mData = d;
var.mAssembler = true;
var.mIndex = proc->mModule->mGlobalVars.Size();
if (exp->mDecValue)
{
exp->mDecValue->mVarIndex = var.mIndex;
var.mIdent = exp->mDecValue->mIdent;
}
proc->mModule->mGlobalVars.Push(var);
GrowingArray<InterVariable::Reference> references({ 0 });
cexp = exp;
while (cexp)
{
if (cexp->mAsmInsType != ASMIT_BYTE)
{
int opcode = AsmInsOpcodes[cexp->mAsmInsType][cexp->mAsmInsMode];
if (opcode < 0)
mErrors->Error(cexp->mLocation, "Invalid opcode adressing mode");
d[offset++] = opcode;
}
Declaration* aexp = nullptr;
if (cexp->mLeft)
aexp = cexp->mLeft->mDecValue;
switch (cexp->mAsmInsMode)
{
case ASMIM_IMPLIED:
break;
case ASMIM_IMMEDIATE:
if (aexp->mType == DT_CONST_INTEGER)
d[offset++] = cexp->mLeft->mDecValue->mInteger & 255;
else if (aexp->mType == DT_LABEL_REF)
{
if (aexp->mBase->mBase->mVarIndex < 0)
{
InterCodeBasicBlock* bblock = nullptr;
TranslateExpression(procType, proc, bblock, aexp->mBase->mBase->mValue, breakBlock, continueBlock);
}
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = aexp->mFlags & DTF_UPPER_BYTE;
ref.mLower = !(aexp->mFlags & DTF_UPPER_BYTE);
ref.mAddr = offset;
ref.mIndex = aexp->mBase->mBase->mVarIndex;
ref.mOffset = aexp->mOffset + aexp->mBase->mInteger;
references.Push(ref);
offset += 1;
}
break;
case ASMIM_ZERO_PAGE:
case ASMIM_ZERO_PAGE_X:
case ASMIM_INDIRECT_X:
case ASMIM_INDIRECT_Y:
d[offset++] = aexp->mInteger;
break;
case ASMIM_ABSOLUTE:
case ASMIM_INDIRECT:
case ASMIM_ABSOLUTE_X:
case ASMIM_ABSOLUTE_Y:
if (aexp->mType == DT_CONST_INTEGER)
{
d[offset++] = cexp->mLeft->mDecValue->mInteger & 255;
d[offset++] = cexp->mLeft->mDecValue->mInteger >> 8;
}
else if (aexp->mType == DT_LABEL)
{
if (aexp->mBase->mVarIndex < 0)
{
InterCodeBasicBlock* bblock = nullptr;
TranslateExpression(procType, proc, bblock, aexp->mBase->mValue, breakBlock, continueBlock);
}
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = true;
ref.mLower = true;
ref.mAddr = offset;
ref.mIndex = aexp->mBase->mVarIndex;
ref.mOffset = aexp->mInteger;
references.Push(ref);
offset += 2;
}
else if (aexp->mType == DT_LABEL_REF)
{
if (aexp->mBase->mBase->mVarIndex < 0)
{
InterCodeBasicBlock* bblock = nullptr;
TranslateExpression(procType, proc, bblock, aexp->mBase->mBase->mValue, breakBlock, continueBlock);
}
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = true;
ref.mLower = true;
ref.mAddr = offset;
ref.mIndex = aexp->mBase->mBase->mVarIndex;
ref.mOffset = aexp->mOffset + aexp->mBase->mInteger;
references.Push(ref);
offset += 2;
}
else if (aexp->mType == DT_CONST_ASSEMBLER)
{
if (aexp->mVarIndex < 0)
{
InterCodeBasicBlock* bblock = nullptr;
TranslateExpression(procType, proc, bblock, aexp->mValue, breakBlock, continueBlock);
}
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = true;
ref.mLower = true;
ref.mAddr = offset;
ref.mIndex = aexp->mVarIndex;
ref.mOffset = 0;
references.Push(ref);
offset += 2;
}
else if (aexp->mType == DT_VARIABLE)
{
if (aexp->mFlags & DTF_GLOBAL)
{
InitGlobalVariable(proc->mModule, aexp);
InterVariable::Reference ref;
ref.mFunction = false;
ref.mUpper = true;
ref.mLower = true;
ref.mAddr = offset;
ref.mIndex = aexp->mVarIndex;
ref.mOffset = 0;
references.Push(ref);
offset += 2;
}
}
break;
case ASMIM_RELATIVE:
d[offset] = aexp->mInteger - offset - 1;
offset++;
break;
}
cexp = cexp->mRight;
}
assert(offset == osize);
InterVariable& ivar(proc->mModule->mGlobalVars[var.mIndex]);
ivar.mNumReferences = references.Size();
if (ivar.mNumReferences)
{
ivar.mReferences = new InterVariable::Reference[ivar.mNumReferences];
for (int i = 0; i < ivar.mNumReferences; i++)
ivar.mReferences[i] = references[i];
}
Declaration* dec = exp->mDecValue;
if (block)
{
InterInstruction* ins = new InterInstruction();
ins->mCode = IC_CONSTANT;
ins->mTType = IT_POINTER;
ins->mTTemp = proc->AddTemporary(ins->mTType);
ins->mOperandSize = dec->mSize;
ins->mIntValue = 0;
ins->mMemory = IM_GLOBAL;
ins->mVarIndex = var.mIndex;
ins->mLinkerObject = dec->mLinkerObject;
ins->mVarIndex = dec->mVarIndex;
block->Append(ins);
InterInstruction * jins = new InterInstruction();
@ -2233,7 +2071,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
}
}
void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int offset, Declaration* data, GrowingArray<InterVariable::Reference>& references)
void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int offset, Declaration* data, InterVariable * variable)
{
if (data->mType == DT_CONST_DATA)
{
@ -2244,7 +2082,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
Declaration* mdec = data->mParams;
while (mdec)
{
BuildInitializer(mod, dp, offset + mdec->mOffset, mdec, references);
BuildInitializer(mod, dp, offset + mdec->mOffset, mdec, variable);
mdec = mdec->mNext;
}
}
@ -2276,63 +2114,66 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
}
else if (data->mType == DT_CONST_ASSEMBLER)
{
if (data->mVarIndex < 0)
if (!data->mLinkerObject)
TranslateAssembler(mod, data->mValue);
InterVariable::Reference ref;
ref.mAddr = offset;
ref.mUpper = true;
ref.mLower = true;
ref.mFunction = false;
ref.mIndex = data->mVarIndex;
ref.mOffset = 0;
references.Push(ref);
LinkerReference ref;
ref.mObject = variable->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mRefObject = data->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
}
else if (data->mType == DT_CONST_FUNCTION)
{
if (data->mVarIndex < 0)
if (!data->mLinkerObject)
{
InterCodeProcedure* cproc = this->TranslateProcedure(mod, data->mValue, data);
cproc->ReduceTemporaries();
}
InterVariable::Reference ref;
ref.mAddr = offset;
ref.mLower = true;
ref.mUpper = true;
ref.mFunction = true;
ref.mIndex = data->mVarIndex;
ref.mOffset = 0;
references.Push(ref);
LinkerReference ref;
ref.mObject = variable->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mRefObject = data->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
}
else if (data->mType == DT_CONST_POINTER)
{
Expression* exp = data->mValue;
Declaration* dec = exp->mDecValue;
InterVariable::Reference ref;
ref.mAddr = offset;
ref.mLower = true;
ref.mUpper = true;
LinkerReference ref;
ref.mObject = variable->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
switch (dec->mType)
{
case DT_CONST_DATA:
{
if (dec->mVarIndex < 0)
if (!dec->mLinkerObject)
{
dec->mVarIndex = mod->mGlobalVars.Size();
InterVariable var;
var.mIndex = dec->mVarIndex;
var.mOffset = 0;
var.mSize = dec->mSize;
var.mData = dec->mData;
var.mIdent = dec->mIdent;
InterVariable* var = new InterVariable();
var->mIndex = dec->mVarIndex;
var->mOffset = 0;
var->mSize = dec->mSize;
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA);
dec->mLinkerObject = var->mLinkerObject;
var->mLinkerObject->AddData(dec->mData, dec->mSize);
mod->mGlobalVars.Push(var);
}
ref.mFunction = false;
ref.mIndex = dec->mVarIndex;
ref.mOffset = 0;
references.Push(ref);
ref.mRefObject = dec->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
break;
}
}
@ -2381,8 +2222,10 @@ void InterCodeGenerator::TranslateLogic(Declaration* procType, InterCodeProcedur
InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod, Expression* exp, Declaration * dec)
{
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent);
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent, mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_BYTE_CODE));
dec->mVarIndex = proc->mID;
dec->mLinkerObject = proc->mLinkerObject;
if (mForceNativeCode)
dec->mFlags |= DTF_NATIVE;

View File

@ -2,11 +2,12 @@
#include "Parser.h"
#include "InterCode.h"
#include "Linker.h"
class InterCodeGenerator
{
public:
InterCodeGenerator(Errors * errors);
InterCodeGenerator(Errors * errors, Linker * linker);
~InterCodeGenerator(void);
struct ExValue
@ -27,11 +28,12 @@ public:
protected:
Errors* mErrors;
Linker* mLinker;
ExValue Dereference(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, int level = 0);
ExValue CoerceType(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, Declaration * type);
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock);
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp);
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, GrowingArray<InterVariable::Reference> & references);
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable);
};

View File

@ -2,6 +2,22 @@
#include <string.h>
#include <stdio.h>
void LinkerObject::AddData(const uint8* data, int size)
{
mSize = size;
mData = new uint8[size];
memcpy(mData, data, size);
}
uint8* LinkerObject::AddSpace(int size)
{
mSize = size;
mData = new uint8[size];
memset(mData, 0, size);
return mData;
}
Linker::Linker(Errors* errors)
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr)
{
@ -25,7 +41,7 @@ int Linker::AddSection(const Ident* section, int start, int size)
return lsec->mID;
}
int Linker::AddObject(const Location& location, const Ident* ident, const Ident* section, LinkerObjectType type)
LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, const Ident* section, LinkerObjectType type)
{
LinkerObject* obj = new LinkerObject;
obj->mLocation = location;
@ -36,31 +52,9 @@ int Linker::AddObject(const Location& location, const Ident* ident, const Ident*
obj->mIdent = ident;
obj->mSection = section;
obj->mProc = nullptr;
obj->mReferenced = false;
mObjects.Push(obj);
return obj->mID;
}
void Linker::AddObjectData(int id, const uint8* data, int size)
{
LinkerObject* obj = mObjects[id];
obj->mSize = size;
obj->mData = new uint8[size];
memcpy(obj->mData, data, size);
}
uint8* Linker::AddObjectSpace(int id, int size)
{
LinkerObject* obj = mObjects[id];
obj->mSize = size;
obj->mData = new uint8[size];
memset(obj->mData, 0, size);
return obj->mData;
}
void Linker::AttachObjectProcedure(int id, InterCodeProcedure* proc)
{
LinkerObject* obj = mObjects[id];
obj->mProc = proc;
return obj;
}
void Linker::AddReference(const LinkerReference& ref)
@ -69,30 +63,46 @@ void Linker::AddReference(const LinkerReference& ref)
mReferences.Push(nref);
}
void Linker::ReferenceObject(LinkerObject* obj)
{
if (!obj->mReferenced)
{
obj->mReferenced = true;
for (int i = 0; i < mReferences.Size(); i++)
{
LinkerReference* ref = mReferences[i];
if (ref->mObject == obj)
ReferenceObject(ref->mRefObject);
}
}
}
void Linker::Link(void)
{
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* obj = mObjects[i];
LinkerSection* lsec;
int j = 0;
while (j < mSections.Size() && !(mSections[j]->mIdent == obj->mSection && mSections[j]->mUsed + obj->mSize <= mSections[j]->mSize))
j++;
if (j < mSections.Size())
if (obj->mReferenced)
{
LinkerSection* lsec = mSections[j];
obj->mLinkerSection = lsec;
obj->mAddress = lsec->mUsed;
lsec->mUsed += obj->mSize;
memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize);
LinkerSection* lsec;
int j = 0;
while (j < mSections.Size() && !(mSections[j]->mIdent == obj->mSection && mSections[j]->mUsed + obj->mSize <= mSections[j]->mSize))
j++;
if (j < mSections.Size())
{
LinkerSection* lsec = mSections[j];
obj->mLinkerSection = lsec;
obj->mAddress = lsec->mUsed;
lsec->mUsed += obj->mSize;
}
else
mErrors->Error(obj->mLocation, "Out of space in section", obj->mSection->mString);
}
else
mErrors->Error(obj->mLocation, "Out of space in section", obj->mSection->mString);
}
if (mErrors->mErrorCount == 0)
{
mProgramStart = 0xffff;
mProgramStart = 0x0801;
mProgramEnd = 0x0801;
int address = 0;
@ -114,23 +124,29 @@ void Linker::Link(void)
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* obj = mObjects[i];
obj->mAddress += obj->mLinkerSection->mStart;
if (obj->mReferenced)
{
obj->mAddress += obj->mLinkerSection->mStart;
memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize);
}
}
for (int i = 0; i < mReferences.Size(); i++)
{
LinkerReference* ref = mReferences[i];
LinkerObject* obj = mObjects[ref->mID];
LinkerObject* robj = mObjects[ref->mRefID];
LinkerObject* obj = ref->mObject;
if (obj->mReferenced)
{
LinkerObject* robj = ref->mRefObject;
int raddr = robj->mAddress + ref->mRefOffset;
uint8* dp = mMemory + obj->mAddress + ref->mOffset;
if (ref->mLowByte)
*dp++ = raddr & 0xff;
if (ref->mHighByte)
*dp++ = (raddr >> 8) & 0xff;
int raddr = robj->mAddress + ref->mRefOffset;
uint8* dp = mMemory + obj->mAddress + ref->mOffset;
if (ref->mLowByte)
*dp++ = raddr & 0xff;
if (ref->mHighByte)
*dp++ = (raddr >> 8) & 0xff;
}
}
}
}
@ -175,10 +191,13 @@ bool Linker::WriteMapFile(const char* filename)
{
LinkerObject* obj = mObjects[i];
if (obj->mIdent)
fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
else
fprintf(file, "%04x - %04x : *, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
if (obj->mReferenced)
{
if (obj->mIdent)
fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
else
fprintf(file, "%04x - %04x : *, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, LinkerObjectTypeNames[obj->mType], obj->mSection->mString);
}
}
fclose(file);
@ -199,14 +218,17 @@ bool Linker::WriteAsmFile(const char* filename)
{
LinkerObject* obj = mObjects[i];
switch (obj->mType)
if (obj->mReferenced)
{
case LOT_BYTE_CODE:
mByteCodeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc);
break;
case LOT_NATIVE_CODE:
mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc);
break;
switch (obj->mType)
{
case LOT_BYTE_CODE:
mByteCodeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent);
break;
case LOT_NATIVE_CODE:
mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent);
break;
}
}
}

View File

@ -21,22 +21,27 @@ enum LinkerObjectType
LOT_STACK
};
struct LinkerReference
class LinkerObject;
class LinkerReference
{
int mID, mOffset;
int mRefID, mRefOffset;
public:
LinkerObject* mObject, * mRefObject;
int mOffset, mRefOffset;
bool mLowByte, mHighByte;
};
struct LinkerSection
class LinkerSection
{
public:
const Ident* mIdent;
int mID;
int mStart, mSize, mUsed;
};
struct LinkerObject
class LinkerObject
{
public:
Location mLocation;
const Ident* mIdent, * mSection;
LinkerObjectType mType;
@ -46,6 +51,10 @@ struct LinkerObject
LinkerSection* mLinkerSection;
uint8* mData;
InterCodeProcedure* mProc;
bool mReferenced;
void AddData(const uint8* data, int size);
uint8* AddSpace(int size);
};
class Linker
@ -56,10 +65,7 @@ public:
int AddSection(const Ident* section, int start, int size);
int AddObject(const Location & location, const Ident* ident, const Ident* section, LinkerObjectType type);
void AddObjectData(int id, const uint8* data, int size);
uint8 * AddObjectSpace(int id, int size);
void AttachObjectProcedure(int id, InterCodeProcedure* proc);
LinkerObject * AddObject(const Location & location, const Ident* ident, const Ident* section, LinkerObjectType type);
void AddReference(const LinkerReference& ref);
@ -72,13 +78,14 @@ public:
GrowingArray<LinkerObject*> mObjects;
uint8 mMemory[0x10000];
int mProgramStart, mProgramEnd;
void ReferenceObject(LinkerObject* obj);
void Link(void);
protected:
NativeCodeDisassembler mNativeDisassembler;
ByteCodeDisassembler mByteCodeDisassembler;
int mProgramStart, mProgramEnd;
Errors* mErrors;
};

View File

@ -44,16 +44,8 @@ void NativeRegisterDataSet::ResetZeroPage(int addr)
}
}
NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, AsmInsMode mode, int address, int varIndex, bool lower, bool upper)
: 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);
}

View File

@ -1,10 +1,12 @@
#pragma once
#include "ByteCodeGenerator.h"
#include "Assembler.h"
#include "Linker.h"
#include "InterCode.h"
class NativeCodeProcedure;
class NativeCodeBasicBlock;
class NativeCodeGenerator;
struct NativeRegisterData
{
@ -24,20 +26,22 @@ struct NativeRegisterDataSet
void ResetZeroPage(int addr);
};
static const uint32 NCIF_LOWER = 0x00000001;
static const uint32 NCIF_UPPER = 0x00000002;
static const uint32 NCIF_RUNTIME = 0x00000004;
class NativeCodeInstruction
{
public:
NativeCodeInstruction(AsmInsType type = ASMIT_INV, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, int varIndex = -1, bool lower = true, bool upper = true);
NativeCodeInstruction(AsmInsType type, AsmInsMode mode, const char* runtime, int address = 0, bool lower = true, bool upper = true);
NativeCodeInstruction(const char* runtime);
NativeCodeInstruction(AsmInsType type = ASMIT_INV, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER);
AsmInsType mType;
AsmInsMode mMode;
int mAddress, mVarIndex;
bool mLower, mUpper, mFunction;
const char * mRuntime;
int mAddress;
uint32 mFlags;
uint32 mLive;
LinkerObject* mLinkerObject;
void Assemble(NativeCodeBasicBlock* block);
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
@ -63,7 +67,7 @@ public:
AsmInsType mBranch;
GrowingArray<NativeCodeInstruction> mIns;
GrowingArray<ByteCodeRelocation> mRelocations;
GrowingArray<LinkerReference> mRelocations;
int mOffset, mSize, mNumEntries;
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited;
@ -91,18 +95,18 @@ public:
void StoreValue(InterCodeProcedure* proc, const InterInstruction * ins);
void LoadValue(InterCodeProcedure* proc, const InterInstruction * ins);
void LoadStoreValue(InterCodeProcedure* proc, const InterInstruction * rins, const InterInstruction * wins);
void BinaryOperator(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
void UnaryOperator(InterCodeProcedure* proc, const InterInstruction * ins);
void BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);
void NumericConversion(InterCodeProcedure* proc, const InterInstruction * ins);
void NumericConversion(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void CopyValue(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure* nproc);
void CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins);
void CallFunction(InterCodeProcedure* proc, const InterInstruction * ins);
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void ShiftRegisterLeft(InterCodeProcedure* proc, int reg, int shift);
int ShortMultiply(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins, int index, int mul);
int ShortMultiply(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins, int index, int mul);
bool CheckPredAccuStore(int reg);
@ -124,20 +128,22 @@ public:
class NativeCodeProcedure
{
public:
NativeCodeProcedure(void);
NativeCodeProcedure(NativeCodeGenerator* generator);
~NativeCodeProcedure(void);
NativeCodeBasicBlock* entryBlock, * exitBlock;
NativeCodeBasicBlock** tblocks;
NativeCodeGenerator* mGenerator;
int mProgStart, mProgSize, mIndex;
bool mNoFrame;
int mTempBlocks;
GrowingArray<ByteCodeRelocation> mRelocations;
GrowingArray<LinkerReference> mRelocations;
GrowingArray < NativeCodeBasicBlock*> mBlocks;
void Compile( ByteCodeGenerator * generator, InterCodeProcedure* proc);
void Compile(InterCodeProcedure* proc);
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
NativeCodeBasicBlock* AllocateBlock(void);
NativeCodeBasicBlock* TransientBlock(void);
@ -149,3 +155,24 @@ class NativeCodeProcedure
};
class NativeCodeGenerator
{
public:
NativeCodeGenerator(Errors * errors, Linker* linker);
~NativeCodeGenerator(void);
void RegisterRuntime(const Ident * ident, LinkerObject * object, int offset);
struct Runtime
{
const Ident * mIdent;
LinkerObject * mLinkerObject;
int mOffset;
};
Runtime& ResolveRuntime(const Ident* ident);
Errors* mErrors;
Linker* mLinker;
GrowingArray<Runtime> mRuntime;
};

View File

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

View File

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

View File

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

View File

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