Add auto generation of multiplier tables if variable factor is known to be small

This commit is contained in:
drmortalwombat 2022-02-02 22:05:55 +01:00
parent c6133ce7c0
commit 34220b96e3
10 changed files with 169 additions and 45 deletions

View File

@ -14,21 +14,21 @@ Compiler::Compiler(void)
mErrors = new Errors(); mErrors = new Errors();
mLinker = new Linker(mErrors); mLinker = new Linker(mErrors);
mCompilationUnits = new CompilationUnits(mErrors); mCompilationUnits = new CompilationUnits(mErrors);
mPreprocessor = new Preprocessor(mErrors);
mByteCodeGenerator = new ByteCodeGenerator(mErrors, mLinker);
mInterCodeGenerator = new InterCodeGenerator(mErrors, mLinker);
mNativeCodeGenerator = new NativeCodeGenerator(mErrors, mLinker);
mInterCodeModule = new InterCodeModule();
mGlobalAnalyzer = new GlobalAnalyzer(mErrors, mLinker);
mCompilationUnits->mLinker = mLinker; mCompilationUnits->mLinker = mLinker;
mCompilationUnits->mSectionCode = mLinker->AddSection(Ident::Unique("code"), LST_DATA); mCompilationUnits->mSectionCode = mLinker->AddSection(Ident::Unique("code"), LST_DATA);
mCompilationUnits->mSectionData = mLinker->AddSection(Ident::Unique("data"), LST_DATA); mCompilationUnits->mSectionData = mLinker->AddSection(Ident::Unique("data"), LST_DATA);
mCompilationUnits->mSectionBSS = mLinker->AddSection(Ident::Unique("bss"), LST_BSS); mCompilationUnits->mSectionBSS = mLinker->AddSection(Ident::Unique("bss"), LST_BSS);
mCompilationUnits->mSectionHeap = mLinker->AddSection(Ident::Unique("heap"), LST_HEAP); mCompilationUnits->mSectionHeap = mLinker->AddSection(Ident::Unique("heap"), LST_HEAP);
mCompilationUnits->mSectionStack = mLinker->AddSection(Ident::Unique("stack"), LST_STACK); mCompilationUnits->mSectionStack = mLinker->AddSection(Ident::Unique("stack"), LST_STACK);
mCompilationUnits->mSectionStack->mSize = 4096; mCompilationUnits->mSectionStack->mSize = 4096;
mPreprocessor = new Preprocessor(mErrors);
mByteCodeGenerator = new ByteCodeGenerator(mErrors, mLinker);
mInterCodeGenerator = new InterCodeGenerator(mErrors, mLinker);
mNativeCodeGenerator = new NativeCodeGenerator(mErrors, mLinker, mCompilationUnits->mSectionCode);
mInterCodeModule = new InterCodeModule();
mGlobalAnalyzer = new GlobalAnalyzer(mErrors, mLinker);
} }
Compiler::~Compiler(void) Compiler::~Compiler(void)
@ -343,6 +343,8 @@ bool Compiler::GenerateCode(void)
} }
} }
mNativeCodeGenerator->CompleteRuntime();
mLinker->CollectReferences(); mLinker->CollectReferences();
mLinker->ReferenceObject(dcrtstart->mLinkerObject); mLinker->ReferenceObject(dcrtstart->mLinkerObject);

View File

@ -603,7 +603,7 @@ NativeCodeDisassembler::~NativeCodeDisassembler(void)
} }
void NativeCodeDisassembler::DumpMemory(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker) void NativeCodeDisassembler::DumpMemory(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker, LinkerObject * lobj)
{ {
fprintf(file, "--------------------------------------------------------------------\n"); fprintf(file, "--------------------------------------------------------------------\n");
if (proc && proc->mIdent) if (proc && proc->mIdent)
@ -613,31 +613,38 @@ void NativeCodeDisassembler::DumpMemory(FILE* file, const uint8* memory, int sta
char tbuffer[10], abuffer[100]; char tbuffer[10], abuffer[100];
int ip = start; if (lobj->mSection->mType == LST_BSS)
while (ip < start + size)
{ {
int n = 16; fprintf(file, "%04x : __ __ __ BSS\t%d\n", start, size);
if (ip + n > start + size) }
n = start + size - ip; else
{
fprintf(file, "%04x : __ __ __ BYT", ip); int ip = start;
while (ip < start + size)
for (int i = 0; i < n; i++)
fprintf(file, " %02x", memory[ip + i]);
for(int i=n; i<16; i++)
fprintf(file, " ");
fprintf(file, " : ");
for (int i = 0; i < n; i++)
{ {
int k = memory[ip + i]; int n = 16;
if (k >= 32 && k < 128) if (ip + n > start + size)
fprintf(file, "%c", k); n = start + size - ip;
else
fprintf(file, ".");
}
fprintf(file, "\n");
ip += n; fprintf(file, "%04x : __ __ __ BYT", ip);
for (int i = 0; i < n; i++)
fprintf(file, " %02x", memory[ip + i]);
for (int i = n; i < 16; i++)
fprintf(file, " ");
fprintf(file, " : ");
for (int i = 0; i < n; i++)
{
int k = memory[ip + i];
if (k >= 32 && k < 128)
fprintf(file, "%c", k);
else
fprintf(file, ".");
}
fprintf(file, "\n");
ip += n;
}
} }
} }

View File

@ -7,6 +7,7 @@
class ByteCodeGenerator; class ByteCodeGenerator;
class InterCodeProcedure; class InterCodeProcedure;
class Linker; class Linker;
class LinkerObject;
class ByteCodeDisassembler class ByteCodeDisassembler
{ {
@ -27,7 +28,7 @@ public:
~NativeCodeDisassembler(void); ~NativeCodeDisassembler(void);
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker); void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker);
void DumpMemory(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker); void DumpMemory(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker, LinkerObject * lobj);
protected: protected:
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc); const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc);
const char* AddrName(int addr, char* buffer, Linker* linker); const char* AddrName(int addr, char* buffer, Linker* linker);

View File

@ -646,9 +646,9 @@ bool Linker::WriteAsmFile(const char* filename)
break; break;
case LOT_DATA: case LOT_DATA:
if (obj->mRegion->mCartridge < 0) if (obj->mRegion->mCartridge < 0)
mNativeDisassembler.DumpMemory(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this); mNativeDisassembler.DumpMemory(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this, obj);
else else
mNativeDisassembler.DumpMemory(file, mCartridge[obj->mRegion->mCartridge] - 0x8000, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this); mNativeDisassembler.DumpMemory(file, mCartridge[obj->mRegion->mCartridge] - 0x8000, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this, obj);
} }
} }
} }

View File

@ -4873,6 +4873,36 @@ int NativeCodeBasicBlock::ShortMultiply(InterCodeProcedure* proc, NativeCodeProc
lshift++; lshift++;
} }
if (mul > 1 && (lshift > 3 || lmul != 1) && ins->mSrc[index].IsUByte() && ins->mSrc[index].mRange.mMaxValue < 16)
{
int dreg = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
if (sins)
{
LoadValueToReg(proc, sins, dreg, nullptr, nullptr);
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_ZERO_PAGE, dreg));
}
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[index].mTemp]));
}
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, 0, nproc->mGenerator->AllocateShortMulTable(mul, ins->mSrc[index].mRange.mMaxValue + 1, false)));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, dreg));
if (ins->mDst.IsUByte())
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, dreg + 1));
}
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_X, 0, nproc->mGenerator->AllocateShortMulTable(mul, ins->mSrc[index].mRange.mMaxValue + 1, true)));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, dreg));
}
return dreg;
}
if (lmul == 1 && !sins && ins->mSrc[index].mTemp == ins->mDst.mTemp) if (lmul == 1 && !sins && ins->mSrc[index].mTemp == ins->mDst.mTemp)
{ {
// shift in place // shift in place
@ -14075,6 +14105,26 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true; progress = true;
} }
else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 2].mLive & LIVE_CPU_REG_Y) &&
!mIns[i + 1].UsesZeroPage(mIns[i + 0].mAddress) &&
mIns[i + 2].mType == ASMIT_LDY && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && !(mIns[i + 2].mLive & (LIVE_MEM | LIVE_CPU_REG_Z)))
{
mIns[i + 0].mType = ASMIT_TAY; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_Y;
mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if (
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 2].mLive & LIVE_CPU_REG_X) &&
!mIns[i + 1].UsesZeroPage(mIns[i + 0].mAddress) &&
mIns[i + 2].mType == ASMIT_LDX && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && !(mIns[i + 2].mLive & (LIVE_MEM | LIVE_CPU_REG_Z)))
{
mIns[i + 0].mType = ASMIT_TAX; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_X;
mIns[i + 1].mLive |= LIVE_CPU_REG_X;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true;
}
else if ( else if (
mIns[i + 0].mType == ASMIT_INC && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mType == ASMIT_INC && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && !(mIns[i + 1].mLive & LIVE_MEM) && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == mIns[i + 1].mAddress && !(mIns[i + 1].mLive & LIVE_MEM) &&
@ -16484,8 +16534,8 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
} }
NativeCodeGenerator::NativeCodeGenerator(Errors* errors, Linker* linker) NativeCodeGenerator::NativeCodeGenerator(Errors* errors, Linker* linker, LinkerSection* runtimeSection)
: mErrors(errors), mLinker(linker), mCompilerOptions(COPT_DEFAULT), mRuntime({ 0 }) : mErrors(errors), mLinker(linker), mRuntimeSection(runtimeSection), mCompilerOptions(COPT_DEFAULT), mRuntime({ 0 }), mMulTables({nullptr})
{ {
} }
@ -16494,6 +16544,56 @@ NativeCodeGenerator::~NativeCodeGenerator(void)
} }
void NativeCodeGenerator::CompleteRuntime(void)
{
for (int i = 0; i < mMulTables.Size(); i++)
{
const MulTable& m(mMulTables[i]);
m.mLinkerLSB->AddSpace(m.mSize);
m.mLinkerMSB->AddSpace(m.mSize);
for (int j = 0; j < m.mSize; j++)
{
m.mLinkerLSB->mData[j] = (uint8)(m.mFactor * j);
m.mLinkerMSB->mData[j] = (uint8)(m.mFactor * j >> 8);
}
}
}
LinkerObject* NativeCodeGenerator::AllocateShortMulTable(int factor, int size, bool msb)
{
int i = 0;
while (i < mMulTables.Size() && mMulTables[i].mFactor != factor)
i++;
if (i == mMulTables.Size())
{
Location loc;
MulTable mt;
char name[20];
sprintf_s(name, "__multab%dL", factor);
mt.mLinkerLSB = mLinker->AddObject(loc, Ident::Unique(name), mRuntimeSection, LOT_DATA);
sprintf_s(name, "__multab%dH", factor);
mt.mLinkerMSB = mLinker->AddObject(loc, Ident::Unique(name), mRuntimeSection, LOT_DATA);
mt.mFactor = factor;
mt.mSize = size;
mMulTables.Push(mt);
return msb ? mt.mLinkerMSB : mt.mLinkerLSB;
}
else
{
if (size > mMulTables[i].mSize)
mMulTables[i].mSize = size;
return msb ? mMulTables[i].mLinkerMSB : mMulTables[i].mLinkerLSB;
}
}
NativeCodeGenerator::Runtime& NativeCodeGenerator::ResolveRuntime(const Ident* ident) NativeCodeGenerator::Runtime& NativeCodeGenerator::ResolveRuntime(const Ident* ident)
{ {
int i = 0; int i = 0;

View File

@ -297,10 +297,11 @@ class NativeCodeProcedure
class NativeCodeGenerator class NativeCodeGenerator
{ {
public: public:
NativeCodeGenerator(Errors * errors, Linker* linker); NativeCodeGenerator(Errors * errors, Linker* linker, LinkerSection * runtimeSection);
~NativeCodeGenerator(void); ~NativeCodeGenerator(void);
void RegisterRuntime(const Ident * ident, LinkerObject * object, int offset); void RegisterRuntime(const Ident * ident, LinkerObject * object, int offset);
void CompleteRuntime(void);
uint64 mCompilerOptions; uint64 mCompilerOptions;
@ -311,9 +312,20 @@ public:
int mOffset; int mOffset;
}; };
struct MulTable
{
LinkerObject* mLinkerLSB, * mLinkerMSB;
int mFactor, mSize;
};
LinkerObject* AllocateShortMulTable(int factor, int size, bool msb);
Runtime& ResolveRuntime(const Ident* ident); Runtime& ResolveRuntime(const Ident* ident);
Errors* mErrors; Errors* mErrors;
Linker* mLinker; Linker* mLinker;
LinkerSection* mRuntimeSection;
GrowingArray<Runtime> mRuntime; GrowingArray<Runtime> mRuntime;
GrowingArray<MulTable> mMulTables;
}; };

View File

@ -84,7 +84,9 @@ Declaration* Parser::ParseStructDeclaration(uint32 flags, DecType dt)
if (offset > dec->mSize) if (offset > dec->mSize)
dec->mSize = offset; dec->mSize = offset;
dec->mScope->Insert(mdec->mIdent, mdec); if (dec->mScope->Insert(mdec->mIdent, mdec))
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent->mString);
if (mlast) if (mlast)
mlast->mNext = mdec; mlast->mNext = mdec;
else else

View File

@ -73,7 +73,7 @@ int main2(int argc, const char** argv)
#else #else
strcpy(strProductName, "oscar64"); strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.4.78"); strcpy(strProductVersion, "1.4.79");
#ifdef __APPLE__ #ifdef __APPLE__
uint32_t length = sizeof(basePath); uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,4,78,0 FILEVERSION 1,4,79,0
PRODUCTVERSION 1,4,78,0 PRODUCTVERSION 1,4,79,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "oscar64" VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler" VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.4.78.0" VALUE "FileVersion", "1.4.79.0"
VALUE "InternalName", "oscar64.exe" VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe" VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64" VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.4.78.0" VALUE "ProductVersion", "1.4.79.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -3570,15 +3570,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{A63EF9D9-9EA0-4598-BE7F-C7F90A3FFEAA}" "ProductCode" = "8:{71389DF5-8242-4F93-B029-00DDD7917F3C}"
"PackageCode" = "8:{B344F37B-0769-452A-BFC4-40EB21102D3C}" "PackageCode" = "8:{62C0C282-BD8F-4744-A840-97FC2BF956FF}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0" "AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE" "RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE" "InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.4.78" "ProductVersion" = "8:1.4.79"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"