First shot native code generator

Implements basic load, store compare and add/sub/shift for native compiled functions
This commit is contained in:
drmortalwombat 2021-09-07 22:35:11 +02:00
parent 69a44e90e3
commit 056df56eef
10 changed files with 1589 additions and 185 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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