First shot native code generator
Implements basic load, store compare and add/sub/shift for native compiled functions
This commit is contained in:
parent
69a44e90e3
commit
056df56eef
|
@ -405,7 +405,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
||||||
|
|
||||||
ByteCodeRelocation rl;
|
ByteCodeRelocation rl;
|
||||||
rl.mAddr = block->mCode.Size();
|
rl.mAddr = block->mCode.Size();
|
||||||
rl.mFunction = false;
|
rl.mFunction = mFunction;
|
||||||
rl.mLower = true;
|
rl.mLower = true;
|
||||||
rl.mUpper = true;
|
rl.mUpper = true;
|
||||||
rl.mIndex = mVIndex;
|
rl.mIndex = mVIndex;
|
||||||
|
@ -1481,6 +1481,7 @@ void ByteCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInst
|
||||||
ByteCodeInstruction bins(BC_JSR);
|
ByteCodeInstruction bins(BC_JSR);
|
||||||
bins.mRelocate = true;
|
bins.mRelocate = true;
|
||||||
bins.mVIndex = ins.mVarIndex;
|
bins.mVIndex = ins.mVarIndex;
|
||||||
|
bins.mFunction = ins.mMemory == IM_PROCEDURE;
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3394,78 +3395,88 @@ void ByteCodeGenerator::WriteAsmFile(FILE* file)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mGlobalAddr.Size(); i++)
|
for (int i = 0; i < mGlobalAddr.Size(); i++)
|
||||||
{
|
{
|
||||||
if (mGlobalAddr[i].mAssembler)
|
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)
|
||||||
{
|
{
|
||||||
fprintf(file, "--------------------------------------------------------------------\n");
|
int iip = ip;
|
||||||
if (mGlobalAddr[i].mIdent)
|
uint8 opcode = mMemory[ip++];
|
||||||
fprintf(file, "%s:\n", mGlobalAddr[i].mIdent->mString);
|
AsmInsData d = DecInsData[opcode];
|
||||||
|
int addr = 0;
|
||||||
|
|
||||||
int ip = mGlobalAddr[i].mAddress;
|
switch (d.mMode)
|
||||||
while (ip < mGlobalAddr[i].mAddress + mGlobalAddr[i].mSize)
|
|
||||||
{
|
{
|
||||||
int iip = ip;
|
case ASMIM_IMPLIED:
|
||||||
uint8 opcode = mMemory[ip++];
|
fprintf(file, "%04x : %02x __ __ %s\n", iip, mMemory[ip], AsmInstructionNames[d.mType]);
|
||||||
AsmInsData d = DecInsData[opcode];
|
break;
|
||||||
int addr = 0;
|
case ASMIM_IMMEDIATE:
|
||||||
|
addr = mMemory[ip++];
|
||||||
switch (d.mMode)
|
fprintf(file, "%04x : %02x %02x __ %s #$%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
{
|
break;
|
||||||
case ASMIM_IMPLIED:
|
case ASMIM_ZERO_PAGE:
|
||||||
fprintf(file, "%04x : %04x %02x __ __ %s\n", iip, ip, mMemory[ip], AsmInstructionNames[d.mType]);
|
addr = mMemory[ip++];
|
||||||
break;
|
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
case ASMIM_IMMEDIATE:
|
break;
|
||||||
addr = mMemory[ip++];
|
case ASMIM_ZERO_PAGE_X:
|
||||||
fprintf(file, "%04x : %04x %02x %02x __ %s #$%02x\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
addr = mMemory[ip++];
|
||||||
break;
|
fprintf(file, "%04x : %02x %02x __ %s $%02x,x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
case ASMIM_ZERO_PAGE:
|
break;
|
||||||
addr = mMemory[ip++];
|
case ASMIM_ZERO_PAGE_Y:
|
||||||
fprintf(file, "%04x : %04x %02x %02x __ %s $%02x\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
addr = mMemory[ip++];
|
||||||
break;
|
fprintf(file, "%04x : %02x %02x __ %s $%02x,y\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
case ASMIM_ZERO_PAGE_X:
|
break;
|
||||||
addr = mMemory[ip++];
|
case ASMIM_ABSOLUTE:
|
||||||
fprintf(file, "%04x : %04x %02x %02x __ %s $%02x,x\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||||
break;
|
fprintf(file, "%04x : %02x %02x %02x %s $%04x\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
||||||
case ASMIM_ZERO_PAGE_Y:
|
ip += 2;
|
||||||
addr = mMemory[ip++];
|
break;
|
||||||
fprintf(file, "%04x : %04x %02x %02x __ %s $%02x,y\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
case ASMIM_ABSOLUTE_X:
|
||||||
break;
|
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||||
case ASMIM_ABSOLUTE:
|
fprintf(file, "%04x : %02x %02x %02x %s $%04x,x\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
||||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
ip += 2;
|
||||||
fprintf(file, "%04x : %04x %02x %02x %02x %s $%04x\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
break;
|
||||||
ip += 2;
|
case ASMIM_ABSOLUTE_Y:
|
||||||
break;
|
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||||
case ASMIM_ABSOLUTE_X:
|
fprintf(file, "%04x : %02x %02x %02x %s $%04x,y\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
||||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
ip += 2;
|
||||||
fprintf(file, "%04x : %04x %02x %02x %02x %s $%04x,x\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
break;
|
||||||
ip += 2;
|
case ASMIM_INDIRECT:
|
||||||
break;
|
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||||
case ASMIM_ABSOLUTE_Y:
|
ip += 2;
|
||||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
fprintf(file, "%04x : %02x %02x %02x %s ($%04x)\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
||||||
fprintf(file, "%04x : %04x %02x %02x %02x %s $%04x,y\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
break;
|
||||||
ip += 2;
|
case ASMIM_INDIRECT_X:
|
||||||
break;
|
addr = mMemory[ip++];
|
||||||
case ASMIM_INDIRECT:
|
fprintf(file, "%04x : %02x %02x __ %s ($%02x,x)\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
break;
|
||||||
ip += 2;
|
case ASMIM_INDIRECT_Y:
|
||||||
fprintf(file, "%04x : %04x %02x %02x %02x %s ($%04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
addr = mMemory[ip++];
|
||||||
break;
|
fprintf(file, "%04x : %02x %02x __ %s ($%02x),y\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
case ASMIM_INDIRECT_X:
|
break;
|
||||||
addr = mMemory[ip++];
|
case ASMIM_RELATIVE:
|
||||||
fprintf(file, "%04x : %04x %02x %02x __ %s ($%02x,x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
addr = mMemory[ip++];
|
||||||
break;
|
if (addr & 0x80)
|
||||||
case ASMIM_INDIRECT_Y:
|
addr = addr + ip - 256;
|
||||||
addr = mMemory[ip++];
|
else
|
||||||
fprintf(file, "%04x : %04x %02x %02x __ %s ($%02x),y\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
addr = addr + ip;
|
||||||
break;
|
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
case ASMIM_RELATIVE:
|
break;
|
||||||
addr = mMemory[ip++];
|
|
||||||
if (addr & 0x80)
|
|
||||||
addr = addr + ip - 256;
|
|
||||||
else
|
|
||||||
addr = addr + ip;
|
|
||||||
fprintf(file, "%04x : %04x %02x %02x __ %s $%02x\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,26 +253,11 @@ public:
|
||||||
ByteCodeGenerator(void);
|
ByteCodeGenerator(void);
|
||||||
~ByteCodeGenerator(void);
|
~ByteCodeGenerator(void);
|
||||||
|
|
||||||
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 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);
|
|
||||||
|
|
||||||
struct Address
|
struct Address
|
||||||
{
|
{
|
||||||
int mIndex, mAddress, mSize;
|
int mIndex, mAddress, mSize;
|
||||||
bool mFunction, mAssembler;
|
bool mFunction, mAssembler;
|
||||||
const Ident * mIdent;
|
const Ident* mIdent;
|
||||||
};
|
};
|
||||||
|
|
||||||
GrowingArray<Address> mProcedureAddr, mGlobalAddr;
|
GrowingArray<Address> mProcedureAddr, mGlobalAddr;
|
||||||
|
@ -282,4 +267,22 @@ public:
|
||||||
|
|
||||||
uint8 mMemory[0x10000];
|
uint8 mMemory[0x10000];
|
||||||
int mProgEnd, mProgStart, mProgEntry;
|
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);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "InterCodeGenerator.h"
|
#include "InterCodeGenerator.h"
|
||||||
#include "InterCode.h"
|
#include "InterCode.h"
|
||||||
#include "ByteCodeGenerator.h"
|
#include "ByteCodeGenerator.h"
|
||||||
|
#include "NativeCodeGenerator.h"
|
||||||
#include "Emulator.h"
|
#include "Emulator.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
@ -85,27 +86,38 @@ bool Compiler::GenerateCode(void)
|
||||||
|
|
||||||
for (int i = 0; i < mInterCodeModule->mProcedures.Size(); i++)
|
for (int i = 0; i < mInterCodeModule->mProcedures.Size(); i++)
|
||||||
{
|
{
|
||||||
ByteCodeProcedure* bgproc = new ByteCodeProcedure();
|
InterCodeProcedure* proc = mInterCodeModule->mProcedures[i];
|
||||||
|
|
||||||
mInterCodeModule->mProcedures[i]->ReduceTemporaries();
|
proc->ReduceTemporaries();
|
||||||
|
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
mInterCodeModule->mProcedures[i]->Disassemble("final");
|
proc->Disassemble("final");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bgproc->Compile(mByteCodeGenerator, mInterCodeModule->mProcedures[i]);
|
|
||||||
mByteCodeFunctions.Push(bgproc);
|
|
||||||
|
|
||||||
#if _DEBUG
|
if (proc->mNativeProcedure)
|
||||||
FILE* file;
|
|
||||||
fopen_s(&file, "r:\\cldiss.txt", "a");
|
|
||||||
|
|
||||||
if (file)
|
|
||||||
{
|
{
|
||||||
bgproc->Disassemble(file, mByteCodeGenerator, mInterCodeModule->mProcedures[i]);
|
NativeCodeProcedure* ncproc = new NativeCodeProcedure();
|
||||||
fclose(file);
|
ncproc->Compile(mByteCodeGenerator, proc);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ByteCodeProcedure* bgproc = new ByteCodeProcedure();
|
||||||
|
|
||||||
|
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
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 128; i++)
|
for (int i = 0; i < 128; i++)
|
||||||
|
|
|
@ -52,6 +52,7 @@ static const uint32 DTF_STATIC = 0x00000020;
|
||||||
static const uint32 DTF_CONST = 0x00000040;
|
static const uint32 DTF_CONST = 0x00000040;
|
||||||
static const uint32 DTF_VOLATILE = 0x00000080;
|
static const uint32 DTF_VOLATILE = 0x00000080;
|
||||||
static const uint32 DTF_EXTERN = 0x00000100;
|
static const uint32 DTF_EXTERN = 0x00000100;
|
||||||
|
static const uint32 DTF_NATIVE = 0x00000200;
|
||||||
|
|
||||||
class Declaration;
|
class Declaration;
|
||||||
|
|
||||||
|
|
|
@ -2554,9 +2554,12 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
|
||||||
|
|
||||||
switch (mInstructions[i].mCode)
|
switch (mInstructions[i].mCode)
|
||||||
{
|
{
|
||||||
|
case IC_CONSTANT:
|
||||||
|
if (mInstructions[i].mTType != IT_POINTER)
|
||||||
|
break;
|
||||||
|
|
||||||
case IC_STORE:
|
case IC_STORE:
|
||||||
case IC_LOAD:
|
case IC_LOAD:
|
||||||
case IC_CONSTANT:
|
|
||||||
case IC_JSR:
|
case IC_JSR:
|
||||||
if (mInstructions[i].mMemory == IM_GLOBAL)
|
if (mInstructions[i].mMemory == IM_GLOBAL)
|
||||||
{
|
{
|
||||||
|
@ -2619,7 +2622,7 @@ bool InterCodeBasicBlock::IsLeafProcedure(void)
|
||||||
mVisited = true;
|
mVisited = true;
|
||||||
|
|
||||||
for (i = 0; i < mInstructions.Size(); i++)
|
for (i = 0; i < mInstructions.Size(); i++)
|
||||||
if (mInstructions[i].mCode == IC_CALL)
|
if (mInstructions[i].mCode == IC_CALL || mInstructions[i].mCode == IC_JSR)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mTrueJump && !mTrueJump->IsLeafProcedure())
|
if (mTrueJump && !mTrueJump->IsLeafProcedure())
|
||||||
|
@ -2631,6 +2634,91 @@ bool InterCodeBasicBlock::IsLeafProcedure(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeBasicBlock::PeepholeOptimization(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
bool changed;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
for (i = 0; i < mInstructions.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mInstructions[i].mCode != IC_NONE)
|
||||||
|
{
|
||||||
|
mInstructions[j++] = mInstructions[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mInstructions.SetSize(j);
|
||||||
|
|
||||||
|
changed = false;
|
||||||
|
|
||||||
|
for (i = 0; i < mInstructions.Size(); i++)
|
||||||
|
{
|
||||||
|
if (i + 2 < mInstructions.Size())
|
||||||
|
{
|
||||||
|
if (mInstructions[i + 0].mTTemp >= 0 &&
|
||||||
|
mInstructions[i + 1].mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1].mSTemp[0] == mInstructions[i].mTTemp &&
|
||||||
|
(mInstructions[i + 2].mCode == IC_RELATIONAL_OPERATOR || mInstructions[i + 2].mCode == IC_BINARY_OPERATOR) && mInstructions[i + 2].mSTemp[0] == mInstructions[i].mTTemp && mInstructions[i + 2].mSFinal[0])
|
||||||
|
{
|
||||||
|
mInstructions[i + 0].mTTemp = mInstructions[i + 1].mTTemp;
|
||||||
|
mInstructions[i + 1].mCode = IC_NONE;
|
||||||
|
mInstructions[i + 2].mSTemp[0] = mInstructions[i + 1].mTTemp;
|
||||||
|
mInstructions[i + 2].mSFinal[0] = false;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (mInstructions[i + 0].mTTemp >= 0 &&
|
||||||
|
mInstructions[i + 1].mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1].mSTemp[0] == mInstructions[i].mTTemp &&
|
||||||
|
(mInstructions[i + 2].mCode == IC_RELATIONAL_OPERATOR || mInstructions[i + 2].mCode == IC_BINARY_OPERATOR) && mInstructions[i + 2].mSTemp[1] == mInstructions[i].mTTemp && mInstructions[i + 2].mSFinal[1])
|
||||||
|
{
|
||||||
|
mInstructions[i + 0].mTTemp = mInstructions[i + 1].mTTemp;
|
||||||
|
mInstructions[i + 1].mCode = IC_NONE;
|
||||||
|
mInstructions[i + 2].mSTemp[1] = mInstructions[i + 1].mTTemp;
|
||||||
|
mInstructions[i + 2].mSFinal[1] = false;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Postincrement artifact
|
||||||
|
if (mInstructions[i + 0].mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1].mCode == IC_BINARY_OPERATOR &&
|
||||||
|
mInstructions[i + 1].mSTemp[0] < 0 &&
|
||||||
|
mInstructions[i + 0].mSTemp[0] == mInstructions[i + 1].mSTemp[1] &&
|
||||||
|
mInstructions[i + 0].mSTemp[0] == mInstructions[i + 1].mTTemp)
|
||||||
|
{
|
||||||
|
InterInstruction ins = mInstructions[i + 1];
|
||||||
|
int ttemp = mInstructions[i + 1].mTTemp;
|
||||||
|
int k = i + 1;
|
||||||
|
while (k + 2 < mInstructions.Size() &&
|
||||||
|
mInstructions[k + 1].mSTemp[0] != ttemp &&
|
||||||
|
mInstructions[k + 1].mSTemp[1] != ttemp &&
|
||||||
|
mInstructions[k + 1].mSTemp[2] != ttemp &&
|
||||||
|
mInstructions[k + 1].mTTemp != ttemp)
|
||||||
|
{
|
||||||
|
mInstructions[k] = mInstructions[k + 1];
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
if (k > i + 1)
|
||||||
|
{
|
||||||
|
mInstructions[k] = ins;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (changed);
|
||||||
|
|
||||||
|
if (mTrueJump) mTrueJump->PeepholeOptimization();
|
||||||
|
if (mFalseJump) mFalseJump->PeepholeOptimization();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars)
|
void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, GrowingVariableArray& localVars)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -2783,7 +2871,7 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
|
||||||
: mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1),
|
: mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1),
|
||||||
mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1),
|
mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1),
|
||||||
mValueForwardingTable(NULL), mLocalVars(InterVariable()), mModule(mod),
|
mValueForwardingTable(NULL), mLocalVars(InterVariable()), mModule(mod),
|
||||||
mIdent(ident)
|
mIdent(ident), mNativeProcedure(false), mLeafProcedure(false)
|
||||||
{
|
{
|
||||||
mID = mModule->mProcedures.Size();
|
mID = mModule->mProcedures.Size();
|
||||||
mModule->mProcedures.Push(this);
|
mModule->mProcedures.Push(this);
|
||||||
|
@ -2964,6 +3052,27 @@ void InterCodeProcedure::TempForwarding(void)
|
||||||
DisassembleDebug("temp forwarding");
|
DisassembleDebug("temp forwarding");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeProcedure::RemoveUnusedInstructions(void)
|
||||||
|
{
|
||||||
|
int numTemps = mTemporaries.Size();
|
||||||
|
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
mBlocks[0]->BuildLocalTempSets(numTemps, numFixedTemporaries);
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mBlocks[0]->BuildGlobalProvidedTempSet(NumberSet(numTemps));
|
||||||
|
|
||||||
|
NumberSet totalRequired2(numTemps);
|
||||||
|
|
||||||
|
do {
|
||||||
|
ResetVisited();
|
||||||
|
} while (mBlocks[0]->BuildGlobalRequiredTempSet(totalRequired2));
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
} while (mBlocks[0]->RemoveUnusedResultInstructions(numFixedTemporaries));
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::Close(void)
|
void InterCodeProcedure::Close(void)
|
||||||
{
|
{
|
||||||
int i, j, k, start;
|
int i, j, k, start;
|
||||||
|
@ -3139,25 +3248,18 @@ void InterCodeProcedure::Close(void)
|
||||||
// Now remove unused instructions
|
// Now remove unused instructions
|
||||||
//
|
//
|
||||||
|
|
||||||
do {
|
RemoveUnusedInstructions();
|
||||||
ResetVisited();
|
|
||||||
mBlocks[0]->BuildLocalTempSets(numTemps, numFixedTemporaries);
|
|
||||||
|
|
||||||
ResetVisited();
|
|
||||||
mBlocks[0]->BuildGlobalProvidedTempSet(NumberSet(numTemps));
|
|
||||||
|
|
||||||
NumberSet totalRequired2(numTemps);
|
|
||||||
|
|
||||||
do {
|
|
||||||
ResetVisited();
|
|
||||||
} while (mBlocks[0]->BuildGlobalRequiredTempSet(totalRequired2));
|
|
||||||
|
|
||||||
ResetVisited();
|
|
||||||
} while (mBlocks[0]->RemoveUnusedResultInstructions(numFixedTemporaries));
|
|
||||||
|
|
||||||
DisassembleDebug("removed unused instructions 2");
|
DisassembleDebug("removed unused instructions 2");
|
||||||
|
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
mBlocks[0]->PeepholeOptimization();
|
||||||
|
|
||||||
|
TempForwarding();
|
||||||
|
RemoveUnusedInstructions();
|
||||||
|
|
||||||
|
DisassembleDebug("Peephole optimized");
|
||||||
|
|
||||||
FastNumberSet activeSet(numTemps);
|
FastNumberSet activeSet(numTemps);
|
||||||
|
|
||||||
|
@ -3173,6 +3275,8 @@ void InterCodeProcedure::Close(void)
|
||||||
|
|
||||||
mTemporaries.SetSize(activeSet.Num());
|
mTemporaries.SetSize(activeSet.Num());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mBlocks[0]->ShrinkActiveTemporaries(activeSet, mTemporaries);
|
mBlocks[0]->ShrinkActiveTemporaries(activeSet, mTemporaries);
|
||||||
|
|
||||||
|
|
|
@ -253,6 +253,9 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef GrowingArray<InterVariable::Reference> GrowingInterVariableReferenceArray;
|
||||||
|
|
||||||
class InterInstruction
|
class InterInstruction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -415,6 +418,8 @@ public:
|
||||||
void CollectOuterFrame(int level, int& size);
|
void CollectOuterFrame(int level, int& size);
|
||||||
|
|
||||||
bool IsLeafProcedure(void);
|
bool IsLeafProcedure(void);
|
||||||
|
|
||||||
|
void PeepholeOptimization(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterCodeModule;
|
class InterCodeModule;
|
||||||
|
@ -434,7 +439,7 @@ public:
|
||||||
GrowingTypeArray mTemporaries;
|
GrowingTypeArray mTemporaries;
|
||||||
GrowingIntArray mTempOffset;
|
GrowingIntArray mTempOffset;
|
||||||
int mTempSize, mCommonFrameSize;
|
int mTempSize, mCommonFrameSize;
|
||||||
bool mLeafProcedure;
|
bool mLeafProcedure, mNativeProcedure;
|
||||||
|
|
||||||
InterCodeModule * mModule;
|
InterCodeModule * mModule;
|
||||||
int mID;
|
int mID;
|
||||||
|
@ -463,6 +468,7 @@ protected:
|
||||||
void BuildDataFlowSets(void);
|
void BuildDataFlowSets(void);
|
||||||
void RenameTemporaries(void);
|
void RenameTemporaries(void);
|
||||||
void TempForwarding(void);
|
void TempForwarding(void);
|
||||||
|
void RemoveUnusedInstructions(void);
|
||||||
|
|
||||||
void DisassembleDebug(const char* name);
|
void DisassembleDebug(const char* name);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1397,7 +1397,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
mErrors->Error(exp->mLocation, "Not enough arguments for function call");
|
mErrors->Error(exp->mLocation, "Not enough arguments for function call");
|
||||||
|
|
||||||
InterInstruction cins;
|
InterInstruction cins;
|
||||||
cins.mCode = IC_CALL;
|
if (exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
|
||||||
|
cins.mCode = IC_JSR;
|
||||||
|
else
|
||||||
|
cins.mCode = IC_CALL;
|
||||||
cins.mSType[0] = IT_POINTER;
|
cins.mSType[0] = IT_POINTER;
|
||||||
cins.mSTemp[0] = vl.mTemp;
|
cins.mSTemp[0] = vl.mTemp;
|
||||||
if (ftype->mBase->mType != DT_TYPE_VOID)
|
if (ftype->mBase->mType != DT_TYPE_VOID)
|
||||||
|
@ -2210,6 +2213,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent);
|
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent);
|
||||||
dec->mVarIndex = proc->mID;
|
dec->mVarIndex = proc->mID;
|
||||||
|
|
||||||
|
if (dec->mFlags & DTF_NATIVE)
|
||||||
|
proc->mNativeProcedure = true;
|
||||||
|
|
||||||
InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock();
|
InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock();
|
||||||
|
|
||||||
proc->Append(entryBlock);
|
proc->Append(entryBlock);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,15 +9,15 @@ class NativeCodeBasicBlock;
|
||||||
class NativeCodeInstruction
|
class NativeCodeInstruction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NativeCodeInstruction(AsmInsType type, AsmInsMode mode);
|
NativeCodeInstruction(AsmInsType type = ASMIT_INV, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, int varIndex = -1, bool lower = true, bool upper = true);
|
||||||
|
|
||||||
AsmInsType mType;
|
AsmInsType mType;
|
||||||
AsmInsMode mMode;
|
AsmInsMode mMode;
|
||||||
|
|
||||||
int mAddress, mVarIndex;
|
int mAddress, mVarIndex;
|
||||||
bool mGlobal;
|
bool mLower, mUpper;
|
||||||
|
|
||||||
void Assemble(ByteCodeGenerator* generator, NativeCodeBasicBlock* block);
|
void Assemble(NativeCodeBasicBlock* block);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeBasicBlock
|
class NativeCodeBasicBlock
|
||||||
|
@ -36,21 +36,30 @@ public:
|
||||||
GrowingArray<ByteCodeRelocation> mRelocations;
|
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||||
|
|
||||||
int mOffset, mSize;
|
int mOffset, mSize;
|
||||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled;
|
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame;
|
||||||
|
|
||||||
int PutBranch(ByteCodeGenerator* generator, AsmInsType code, int offset);
|
int PutBranch(NativeCodeProcedure* proc, AsmInsType code, int offset);
|
||||||
|
int PutJump(NativeCodeProcedure* proc, int offset);
|
||||||
|
|
||||||
NativeCodeBasicBlock* BypassEmptyBlocks(void);
|
NativeCodeBasicBlock* BypassEmptyBlocks(void);
|
||||||
void CalculateOffset(int& total);
|
void CalculateOffset(int& total);
|
||||||
void CopyCode(ByteCodeGenerator* generator, uint8* target);
|
|
||||||
|
|
||||||
void Assemble(ByteCodeGenerator* generator);
|
void CopyCode(NativeCodeProcedure* proc, uint8* target);
|
||||||
|
void Assemble(void);
|
||||||
void Compile(InterCodeProcedure* iproc, NativeCodeProcedure* proc, InterCodeBasicBlock* block);
|
void Compile(InterCodeProcedure* iproc, NativeCodeProcedure* proc, InterCodeBasicBlock* block);
|
||||||
void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
|
void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
|
||||||
|
|
||||||
void PutByte(uint8 code);
|
void PutByte(uint8 code);
|
||||||
void PutWord(uint16 code);
|
void PutWord(uint16 code);
|
||||||
|
|
||||||
|
void LoadConstant(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||||
|
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);
|
||||||
|
void UnaryOperator(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||||
|
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
|
||||||
|
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeProcedure
|
class NativeCodeProcedure
|
||||||
|
@ -62,10 +71,14 @@ class NativeCodeProcedure
|
||||||
NativeCodeBasicBlock* entryBlock, * exitBlock;
|
NativeCodeBasicBlock* entryBlock, * exitBlock;
|
||||||
NativeCodeBasicBlock** tblocks;
|
NativeCodeBasicBlock** tblocks;
|
||||||
|
|
||||||
int mProgStart, mProgSize;
|
int mProgStart, mProgSize, mIndex;
|
||||||
|
bool mNoFrame;
|
||||||
|
|
||||||
void Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc);
|
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||||
|
|
||||||
|
void Compile( ByteCodeGenerator * generator, InterCodeProcedure* proc);
|
||||||
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
||||||
|
NativeCodeBasicBlock* TransientBlock(void);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2106,6 +2106,21 @@ void Parser::ParsePragma(void)
|
||||||
}
|
}
|
||||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(mScanner->mTokenIdent->mString, "native"))
|
||||||
|
{
|
||||||
|
mScanner->NextToken();
|
||||||
|
ConsumeToken(TK_OPEN_PARENTHESIS);
|
||||||
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
Declaration* dec = mGlobals->Lookup(mScanner->mTokenIdent);
|
||||||
|
if (dec && dec->mType == DT_CONST_FUNCTION)
|
||||||
|
dec->mFlags |= DTF_NATIVE;
|
||||||
|
else
|
||||||
|
mErrors->Error(mScanner->mLocation, "Native function not found");
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
|
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||||
|
}
|
||||||
else if (!strcmp(mScanner->mTokenIdent->mString, "startup"))
|
else if (!strcmp(mScanner->mTokenIdent->mString, "startup"))
|
||||||
{
|
{
|
||||||
if (mCompilationUnits->mStartup)
|
if (mCompilationUnits->mStartup)
|
||||||
|
|
Loading…
Reference in New Issue