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;
|
||||
rl.mAddr = block->mCode.Size();
|
||||
rl.mFunction = false;
|
||||
rl.mFunction = mFunction;
|
||||
rl.mLower = true;
|
||||
rl.mUpper = true;
|
||||
rl.mIndex = mVIndex;
|
||||
|
@ -1481,6 +1481,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;
|
||||
mIns.Push(bins);
|
||||
}
|
||||
}
|
||||
|
@ -3394,14 +3395,25 @@ void ByteCodeGenerator::WriteAsmFile(FILE* file)
|
|||
{
|
||||
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 (mGlobalAddr[i].mIdent)
|
||||
fprintf(file, "%s:\n", mGlobalAddr[i].mIdent->mString);
|
||||
if (addr.mIdent)
|
||||
fprintf(file, "%s:\n", addr.mIdent->mString);
|
||||
|
||||
int ip = mGlobalAddr[i].mAddress;
|
||||
while (ip < mGlobalAddr[i].mAddress + mGlobalAddr[i].mSize)
|
||||
int ip = addr.mAddress;
|
||||
while (ip < addr.mAddress + addr.mSize)
|
||||
{
|
||||
int iip = ip;
|
||||
uint8 opcode = mMemory[ip++];
|
||||
|
@ -3411,51 +3423,51 @@ void ByteCodeGenerator::WriteAsmFile(FILE* file)
|
|||
switch (d.mMode)
|
||||
{
|
||||
case ASMIM_IMPLIED:
|
||||
fprintf(file, "%04x : %04x %02x __ __ %s\n", iip, ip, mMemory[ip], AsmInstructionNames[d.mType]);
|
||||
fprintf(file, "%04x : %02x __ __ %s\n", iip, mMemory[ip], AsmInstructionNames[d.mType]);
|
||||
break;
|
||||
case ASMIM_IMMEDIATE:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %04x %02x %02x __ %s #$%02x\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
fprintf(file, "%04x : %02x %02x __ %s #$%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_ZERO_PAGE:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %04x %02x %02x __ %s $%02x\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_ZERO_PAGE_X:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %04x %02x %02x __ %s $%02x,x\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x,x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_ZERO_PAGE_Y:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %04x %02x %02x __ %s $%02x,y\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x,y\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_ABSOLUTE:
|
||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||
fprintf(file, "%04x : %04x %02x %02x %02x %s $%04x\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
||||
fprintf(file, "%04x : %02x %02x %02x %s $%04x\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
||||
ip += 2;
|
||||
break;
|
||||
case ASMIM_ABSOLUTE_X:
|
||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||
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);
|
||||
fprintf(file, "%04x : %02x %02x %02x %s $%04x,x\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
||||
ip += 2;
|
||||
break;
|
||||
case ASMIM_ABSOLUTE_Y:
|
||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||
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);
|
||||
fprintf(file, "%04x : %02x %02x %02x %s $%04x,y\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
||||
ip += 2;
|
||||
break;
|
||||
case ASMIM_INDIRECT:
|
||||
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);
|
||||
fprintf(file, "%04x : %02x %02x %02x %s ($%04x)\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_INDIRECT_X:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %04x %02x %02x __ %s ($%02x,x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
fprintf(file, "%04x : %02x %02x __ %s ($%02x,x)\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_INDIRECT_Y:
|
||||
addr = mMemory[ip++];
|
||||
fprintf(file, "%04x : %04x %02x %02x __ %s ($%02x),y\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
fprintf(file, "%04x : %02x %02x __ %s ($%02x),y\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
case ASMIM_RELATIVE:
|
||||
addr = mMemory[ip++];
|
||||
|
@ -3463,13 +3475,12 @@ void ByteCodeGenerator::WriteAsmFile(FILE* file)
|
|||
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);
|
||||
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ByteCodeGenerator::WriteMapFile(const char* filename)
|
||||
{
|
||||
|
|
|
@ -253,21 +253,6 @@ public:
|
|||
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
|
||||
{
|
||||
int mIndex, mAddress, mSize;
|
||||
|
@ -282,4 +267,22 @@ public:
|
|||
|
||||
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);
|
||||
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "InterCodeGenerator.h"
|
||||
#include "InterCode.h"
|
||||
#include "ByteCodeGenerator.h"
|
||||
#include "NativeCodeGenerator.h"
|
||||
#include "Emulator.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -85,15 +86,25 @@ bool Compiler::GenerateCode(void)
|
|||
|
||||
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
|
||||
mInterCodeModule->mProcedures[i]->Disassemble("final");
|
||||
proc->Disassemble("final");
|
||||
#endif
|
||||
|
||||
bgproc->Compile(mByteCodeGenerator, mInterCodeModule->mProcedures[i]);
|
||||
|
||||
if (proc->mNativeProcedure)
|
||||
{
|
||||
NativeCodeProcedure* ncproc = new NativeCodeProcedure();
|
||||
ncproc->Compile(mByteCodeGenerator, proc);
|
||||
}
|
||||
else
|
||||
{
|
||||
ByteCodeProcedure* bgproc = new ByteCodeProcedure();
|
||||
|
||||
bgproc->Compile(mByteCodeGenerator, proc);
|
||||
mByteCodeFunctions.Push(bgproc);
|
||||
|
||||
#if _DEBUG
|
||||
|
@ -107,6 +118,7 @@ bool Compiler::GenerateCode(void)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
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_VOLATILE = 0x00000080;
|
||||
static const uint32 DTF_EXTERN = 0x00000100;
|
||||
static const uint32 DTF_NATIVE = 0x00000200;
|
||||
|
||||
class Declaration;
|
||||
|
||||
|
|
|
@ -2554,9 +2554,12 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
|
|||
|
||||
switch (mInstructions[i].mCode)
|
||||
{
|
||||
case IC_CONSTANT:
|
||||
if (mInstructions[i].mTType != IT_POINTER)
|
||||
break;
|
||||
|
||||
case IC_STORE:
|
||||
case IC_LOAD:
|
||||
case IC_CONSTANT:
|
||||
case IC_JSR:
|
||||
if (mInstructions[i].mMemory == IM_GLOBAL)
|
||||
{
|
||||
|
@ -2619,7 +2622,7 @@ bool InterCodeBasicBlock::IsLeafProcedure(void)
|
|||
mVisited = true;
|
||||
|
||||
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;
|
||||
|
||||
if (mTrueJump && !mTrueJump->IsLeafProcedure())
|
||||
|
@ -2631,6 +2634,91 @@ bool InterCodeBasicBlock::IsLeafProcedure(void)
|
|||
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)
|
||||
{
|
||||
int i;
|
||||
|
@ -2783,7 +2871,7 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
|
|||
: mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1),
|
||||
mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1),
|
||||
mValueForwardingTable(NULL), mLocalVars(InterVariable()), mModule(mod),
|
||||
mIdent(ident)
|
||||
mIdent(ident), mNativeProcedure(false), mLeafProcedure(false)
|
||||
{
|
||||
mID = mModule->mProcedures.Size();
|
||||
mModule->mProcedures.Push(this);
|
||||
|
@ -2964,6 +3052,27 @@ void InterCodeProcedure::TempForwarding(void)
|
|||
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)
|
||||
{
|
||||
int i, j, k, start;
|
||||
|
@ -3139,25 +3248,18 @@ void InterCodeProcedure::Close(void)
|
|||
// Now remove unused instructions
|
||||
//
|
||||
|
||||
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));
|
||||
RemoveUnusedInstructions();
|
||||
|
||||
DisassembleDebug("removed unused instructions 2");
|
||||
|
||||
|
||||
ResetVisited();
|
||||
mBlocks[0]->PeepholeOptimization();
|
||||
|
||||
TempForwarding();
|
||||
RemoveUnusedInstructions();
|
||||
|
||||
DisassembleDebug("Peephole optimized");
|
||||
|
||||
FastNumberSet activeSet(numTemps);
|
||||
|
||||
|
@ -3173,6 +3275,8 @@ void InterCodeProcedure::Close(void)
|
|||
|
||||
mTemporaries.SetSize(activeSet.Num());
|
||||
|
||||
|
||||
|
||||
ResetVisited();
|
||||
mBlocks[0]->ShrinkActiveTemporaries(activeSet, mTemporaries);
|
||||
|
||||
|
|
|
@ -253,6 +253,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
typedef GrowingArray<InterVariable::Reference> GrowingInterVariableReferenceArray;
|
||||
|
||||
class InterInstruction
|
||||
{
|
||||
public:
|
||||
|
@ -415,6 +418,8 @@ public:
|
|||
void CollectOuterFrame(int level, int& size);
|
||||
|
||||
bool IsLeafProcedure(void);
|
||||
|
||||
void PeepholeOptimization(void);
|
||||
};
|
||||
|
||||
class InterCodeModule;
|
||||
|
@ -434,7 +439,7 @@ public:
|
|||
GrowingTypeArray mTemporaries;
|
||||
GrowingIntArray mTempOffset;
|
||||
int mTempSize, mCommonFrameSize;
|
||||
bool mLeafProcedure;
|
||||
bool mLeafProcedure, mNativeProcedure;
|
||||
|
||||
InterCodeModule * mModule;
|
||||
int mID;
|
||||
|
@ -463,6 +468,7 @@ protected:
|
|||
void BuildDataFlowSets(void);
|
||||
void RenameTemporaries(void);
|
||||
void TempForwarding(void);
|
||||
void RemoveUnusedInstructions(void);
|
||||
|
||||
void DisassembleDebug(const char* name);
|
||||
};
|
||||
|
|
|
@ -1397,6 +1397,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
mErrors->Error(exp->mLocation, "Not enough arguments for function call");
|
||||
|
||||
InterInstruction cins;
|
||||
if (exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
|
||||
cins.mCode = IC_JSR;
|
||||
else
|
||||
cins.mCode = IC_CALL;
|
||||
cins.mSType[0] = IT_POINTER;
|
||||
cins.mSTemp[0] = vl.mTemp;
|
||||
|
@ -2210,6 +2213,9 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent);
|
||||
dec->mVarIndex = proc->mID;
|
||||
|
||||
if (dec->mFlags & DTF_NATIVE)
|
||||
proc->mNativeProcedure = true;
|
||||
|
||||
InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock();
|
||||
|
||||
proc->Append(entryBlock);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,15 +9,15 @@ class NativeCodeBasicBlock;
|
|||
class NativeCodeInstruction
|
||||
{
|
||||
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;
|
||||
AsmInsMode mMode;
|
||||
|
||||
int mAddress, mVarIndex;
|
||||
bool mGlobal;
|
||||
bool mLower, mUpper;
|
||||
|
||||
void Assemble(ByteCodeGenerator* generator, NativeCodeBasicBlock* block);
|
||||
void Assemble(NativeCodeBasicBlock* block);
|
||||
};
|
||||
|
||||
class NativeCodeBasicBlock
|
||||
|
@ -36,21 +36,30 @@ public:
|
|||
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||
|
||||
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);
|
||||
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 Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
|
||||
|
||||
void PutByte(uint8 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
|
||||
|
@ -62,10 +71,14 @@ class NativeCodeProcedure
|
|||
NativeCodeBasicBlock* entryBlock, * exitBlock;
|
||||
NativeCodeBasicBlock** tblocks;
|
||||
|
||||
int mProgStart, mProgSize;
|
||||
int mProgStart, mProgSize, mIndex;
|
||||
bool mNoFrame;
|
||||
|
||||
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||
|
||||
void Compile( ByteCodeGenerator * generator, InterCodeProcedure* proc);
|
||||
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
|
||||
NativeCodeBasicBlock* TransientBlock(void);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -2106,6 +2106,21 @@ void Parser::ParsePragma(void)
|
|||
}
|
||||
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"))
|
||||
{
|
||||
if (mCompilationUnits->mStartup)
|
||||
|
|
Loading…
Reference in New Issue