Add source level debug information

This commit is contained in:
drmortalwombat 2023-03-28 21:01:17 +02:00
parent 451eaca2b2
commit 2f1172076a
15 changed files with 3505 additions and 3175 deletions

1
.gitignore vendored
View File

@ -351,3 +351,4 @@ make/oscar64
*.exe
*.d64
*.d64
*.dbj

View File

@ -81,6 +81,7 @@ The compiler is command line driven, and creates an executable .prg file.
* -Os: optimize for size
* -Oi: enable auto inline of small functions (part of O2/O3)
* -Oa: optimize inline assembler (part of O2/O3)
* -g: create source level debug info and add source line numbers to asm listing
* -tf: target format, may be prg, crt or bin
* -tm : target machine
* -d64 : create a d64 disk image

View File

@ -547,6 +547,17 @@ public:
return -1;
}
int IndexOrPush(const T& t)
{
for (int i = 0; i < size; i++)
if (array[i] == t)
return i;
int s = size;
Grow(size + 1, false);
array[s] = t;
return s;
}
bool Contains(const T& t) const
{
for (int i = 0; i < size; i++)

View File

@ -828,7 +828,7 @@ bool Compiler::BuildLZO(const char* targetPath)
bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
{
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200];
char prgPath[200], mapPath[200], asmPath[200], lblPath[200], intPath[200], bcsPath[200], dbjPath[200];
strcpy_s(prgPath, targetPath);
int i = strlen(prgPath);
@ -842,12 +842,14 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
strcpy_s(lblPath, prgPath);
strcpy_s(intPath, prgPath);
strcpy_s(bcsPath, prgPath);
strcpy_s(dbjPath, prgPath);
strcat_s(mapPath, "map");
strcat_s(asmPath, "asm");
strcat_s(lblPath, "lbl");
strcat_s(intPath, "int");
strcat_s(bcsPath, "bcs");
strcat_s(dbjPath, "dbj");
if (mCompilerOptions & COPT_TARGET_PRG)
{
@ -927,6 +929,9 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
printf("Writing <%s>\n", intPath);
mInterCodeModule->Disassemble(intPath);
if (mCompilerOptions & COPT_DEBUGINFO)
WriteDbjFile(dbjPath);
if (!(mCompilerOptions & COPT_NATIVE))
{
if (mCompilerOptions & COPT_VERBOSE)
@ -972,3 +977,130 @@ int Compiler::ExecuteCode(bool profile)
return ecode;
}
bool Compiler::WriteDbjFile(const char* filename)
{
FILE* file;
fopen_s(&file, filename, "wb");
if (file)
{
fprintf(file, "{");
mLinker->WriteDbjFile(file);
fprintf(file, ",\n");
ExpandingArray<Declaration*> types;
fprintf(file, "\tvariables: [\n");
bool first = true;
for (int i = 0; i < mInterCodeModule->mGlobalVars.Size(); i++)
{
InterVariable* v(mInterCodeModule->mGlobalVars[i]);
if (v->mLinkerObject && v->mIdent && v->mDeclaration)
{
if (!first)
fprintf(file, ",\n");
first = false;
fprintf(file, "\t\t{name: \"%s\", start: %d, end: %d, typeid: %d}", v->mIdent->mString, v->mLinkerObject->mAddress, v->mLinkerObject->mAddress + v->mLinkerObject->mSize, types.IndexOrPush(v->mDeclaration->mBase));
}
}
fprintf(file, "\t],\n");
fprintf(file, "\tfunctions: [\n");
first = true;
for (int i = 0; i < mInterCodeModule->mProcedures.Size(); i++)
{
InterCodeProcedure* p(mInterCodeModule->mProcedures[i]);
if (p->mLinkerObject && p->mIdent && p->mDeclaration)
{
if (!first)
fprintf(file, ",\n");
first = false;
fprintf(file, "\t\t{name: \"%s\", start: %d, end: %d, typeid: %d, source: \"%s\", line: %d, lines: [\n",
p->mIdent->mString, p->mLinkerObject->mAddress, p->mLinkerObject->mAddress + p->mLinkerObject->mSize, types.IndexOrPush(p->mDeclaration->mBase),
p->mLocation.mFileName, p->mLocation.mLine);
bool lfirst = true;
LinkerObject* lo = p->mLinkerObject;
for (int j = 0; j < lo->mCodeLocations.Size(); j++)
{
if (!lfirst)
fprintf(file, ",\n");
lfirst = false;
fprintf(file, "\t\t\t{start: %d, end: %d, source: \"%s\", line: %d}",
lo->mCodeLocations[j].mStart + lo->mAddress,
lo->mCodeLocations[j].mEnd + lo->mAddress,
lo->mCodeLocations[j].mLocation.mFileName,
lo->mCodeLocations[j].mLocation.mLine);
}
fprintf(file, "]}");
}
}
fprintf(file, "\t],\n");
first = true;
fprintf(file, "\ttypes: [\n");
for (int i = 0; i < types.Size(); i++)
{
if (!first)
fprintf(file, ",\n");
first = false;
Declaration* dec = types[i];
switch (dec->mType)
{
case DT_TYPE_INTEGER:
if (dec->mFlags & DTF_SIGNED)
fprintf(file, "\t\t{name: \"%s\", typeid: %d, size: %d, type: \"int\"}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
else
fprintf(file, "\t\t{name: \"%s\", typeid: %d, size: %d, type: \"uint\"}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
break;
case DT_TYPE_FLOAT:
fprintf(file, "\t\t{name: \"%s\", typeid: %d, size: %d, type: \"float\"}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
break;
case DT_TYPE_BOOL:
fprintf(file, "\t\t{name: \"%s\", typeid: %d, size: %d, type: \"bool\"}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
break;
case DT_TYPE_ARRAY:
fprintf(file, "\t\t{name: \"%s\", typeid: %d, size: %d, type: \"array\", eid: %d}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize, types.IndexOrPush(dec->mBase));
break;
case DT_TYPE_POINTER:
fprintf(file, "\t\t{name: \"%s\", typeid: %d, size: %d, type: \"ptr\", eid: %d}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize, types.IndexOrPush(dec->mBase));
break;
case DT_TYPE_STRUCT:
{
fprintf(file, "\t\t{name: \"%s\", typeid: %d, size: %d, type: \"struct\", members: [\n", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
bool tfirst = true;
Declaration* mdec = dec->mParams;
while (mdec)
{
if (!tfirst)
fprintf(file, ",\n");
tfirst = false;
fprintf(file, "\t\t\t{name: \"%s\", offset: %d, typeid: %d}", mdec->mIdent->mString, mdec->mOffset, types.IndexOrPush(mdec->mBase));
mdec = mdec->mNext;
}
fprintf(file, "]}");
}
break;
default:
fprintf(file, "\t\t{name: \"%s\", typeid: %d, size: %d}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
}
}
fprintf(file, "\t]");
fprintf(file, "}");
fclose(file);
return true;
}
return false;
}

View File

@ -50,4 +50,6 @@ public:
void RegisterRuntime(const Location& loc, const Ident* ident);
void CompileProcedure(InterCodeProcedure* proc);
bool WriteDbjFile(const char* filename);
};

View File

@ -27,6 +27,8 @@ static const uint64 COPT_VERBOSE = 0x10000000000ULL;
static const uint64 COPT_VERBOSE2 = 0x20000000000ULL;
static const uint64 COPT_VERBOSE3 = 0x40000000000ULL;
static const uint64 COPT_DEBUGINFO = 0x100000000000ULL;
static const uint64 COPT_NATIVE = 0x01000000;
static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;

View File

@ -691,6 +691,12 @@ void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int ba
i++;
if (i < proc->mLinkerObject->mRanges.Size())
fprintf(file, ".%s:\n", proc->mLinkerObject->mRanges[i].mIdent->mString);
i = 0;
while (i < proc->mLinkerObject->mCodeLocations.Size() && iip - start != proc->mLinkerObject->mCodeLocations[i].mStart)
i++;
if (i < proc->mLinkerObject->mCodeLocations.Size())
fprintf(file, ";%4d, \"%s\"\n", proc->mLinkerObject->mCodeLocations[i].mLocation.mLine, proc->mLinkerObject->mCodeLocations[i].mLocation.mFileName);
}
if (bank >= 0)

View File

@ -14180,7 +14180,8 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
mIdent(ident), mLinkerObject(linkerObject),
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false),
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false),
mSaveTempsLinkerObject(nullptr), mValueReturn(false)
mSaveTempsLinkerObject(nullptr), mValueReturn(false),
mDeclaration(nullptr)
{
mID = mModule->mProcedures.Size();
mModule->mProcedures.Push(this);

View File

@ -9,6 +9,8 @@
#include "Ident.h"
#include "Linker.h"
class Declaration;
enum InterCode
{
IC_NONE,
@ -242,9 +244,10 @@ public:
int mNumReferences;
const Ident * mIdent;
LinkerObject * mLinkerObject;
Declaration * mDeclaration;
InterVariable(void)
: mUsed(false), mAliased(false), mTemp(false), mIndex(-1), mSize(0), mOffset(0), mIdent(nullptr), mLinkerObject(nullptr), mTempIndex(-1)
: mUsed(false), mAliased(false), mTemp(false), mIndex(-1), mSize(0), mOffset(0), mIdent(nullptr), mLinkerObject(nullptr), mTempIndex(-1), mDeclaration(nullptr)
{
}
};
@ -572,6 +575,7 @@ public:
const Ident * mIdent, * mSection;
LinkerObject * mLinkerObject, * mSaveTempsLinkerObject;
Declaration * mDeclaration;
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);
~InterCodeProcedure(void);

View File

@ -341,6 +341,7 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
var->mLinkerObject->mFlags |= LOBJF_ZEROPAGE;
var->mIndex = mod->mGlobalVars.Size();
var->mDeclaration = dec;
mod->mGlobalVars.Push(var);
dec->mVarIndex = var->mIndex;
@ -3667,6 +3668,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
dec->mVarIndex = proc->mID;
dec->mLinkerObject = proc->mLinkerObject;
proc->mNumLocals = dec->mNumVars;
proc->mDeclaration = dec;
if (dec->mFlags & DTF_NATIVE)
proc->mNativeProcedure = true;

View File

@ -83,6 +83,13 @@ void LinkerObject::AddData(const uint8* data, int size)
memcpy(mData, data, size);
}
void LinkerObject::AddLocations(const ExpandingArray<CodeLocation>& locations)
{
for (int i = 0; i < locations.Size(); i++)
mCodeLocations.Push(locations[i]);
}
void LinkerObject::EnsureSpace(int offset, int size)
{
if (offset + size > mSize)
@ -1085,6 +1092,36 @@ bool Linker::WriteMlbFile(const char* filename, TargetMachine machine)
return false;
}
bool Linker::WriteDbjFile(FILE* file)
{
fprintf(file, "\tmemory: [");
bool first = true;
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* obj = mObjects[i];
if (obj->mFlags & LOBJF_REFERENCED)
{
if (obj->mIdent)
{
if (!first)
fprintf(file, ",\n");
first = false;
fprintf(file, "\t\t{name: \"%s\", start: %d, end: %d, type: \"%s\", source: \"%s\", line: %d }",
obj->mIdent->mString, obj->mAddress, obj->mAddress + obj->mSize, LinkerObjectTypeNames[obj->mType],
obj->mLocation.mFileName, obj->mLocation.mLine);
}
}
}
fprintf(file, "]");
return true;
}
bool Linker::WriteLblFile(const char* filename)
{
FILE* file;

View File

@ -159,6 +159,13 @@ public:
int mOffset, mSize;
};
struct CodeLocation
{
Location mLocation;
int mStart, mEnd;
};
class LinkerObject
{
public:
@ -179,11 +186,13 @@ public:
LinkerSection * mStackSection;
ExpandingArray<LinkerObjectRange> mRanges;
ExpandingArray<CodeLocation> mCodeLocations;
LinkerObject(void);
~LinkerObject(void);
void AddData(const uint8* data, int size);
void AddLocations(const ExpandingArray<CodeLocation>& locations);
uint8* AddSpace(int size);
void EnsureSpace(int offset, int size);
@ -241,6 +250,7 @@ public:
bool WriteBinFile(const char* filename);
bool WriteNesFile(const char* filename, TargetMachine machine);
bool WriteMlbFile(const char* filename, TargetMachine machine);
bool WriteDbjFile(FILE * file);
int TranslateMlbAddress(int address, int bank, TargetMachine machine);

File diff suppressed because it is too large Load Diff

View File

@ -111,8 +111,9 @@ static const uint32 NICF_USE_WORKREGS = 0x00020000;
class NativeCodeInstruction
{
public:
NativeCodeInstruction(AsmInsType type = ASMIT_INV, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER, int param = 0);
NativeCodeInstruction(AsmInsType type, const NativeCodeInstruction & addr);
NativeCodeInstruction(void);
NativeCodeInstruction(const InterInstruction * ins, AsmInsType type, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, LinkerObject * linkerObject = nullptr, uint32 flags = NCIF_LOWER | NCIF_UPPER, int param = 0);
NativeCodeInstruction(const InterInstruction* ins, AsmInsType type, const NativeCodeInstruction & addr);
AsmInsType mType;
AsmInsMode mMode;
@ -120,7 +121,8 @@ public:
int mAddress, mParam;
uint32 mFlags;
uint32 mLive;
LinkerObject* mLinkerObject;
LinkerObject * mLinkerObject;
const InterInstruction * mIns;
void CopyMode(const NativeCodeInstruction& ins);
@ -191,10 +193,13 @@ public:
~NativeCodeBasicBlock(void);
ExpandingArray<uint8> mCode;
ExpandingArray<CodeLocation> mCodeLocations;
int mIndex;
NativeCodeBasicBlock* mTrueJump, * mFalseJump, * mFromJump;
AsmInsType mBranch;
const InterInstruction* mBranchIns;
ExpandingArray<NativeCodeInstruction> mIns;
ExpandingArray<LinkerReference> mRelocations;
@ -213,7 +218,7 @@ public:
ExpandingArray<NativeRegisterSum16Info> mRSumInfos;
NativeCodeInstruction DecodeNative(LinkerObject * lobj, int& offset) const;
NativeCodeInstruction DecodeNative(const InterInstruction* ins, LinkerObject * lobj, int& offset) const;
int PutBranch(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, AsmInsType code, int offset);
int PutJump(NativeCodeProcedure* proc, NativeCodeBasicBlock* target, int offset);
@ -230,7 +235,7 @@ public:
void CopyCode(NativeCodeProcedure* proc, uint8* target);
void Assemble(void);
void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
void Close(const InterInstruction * ins, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
void PrependInstruction(const NativeCodeInstruction& ins);
@ -278,10 +283,11 @@ public:
NativeCodeBasicBlock* BuildSingleEntry(NativeCodeProcedure* proc, NativeCodeBasicBlock* block);
NativeCodeBasicBlock* BuildSingleExit(NativeCodeProcedure* proc, NativeCodeBasicBlock* block);
void PutLocation(const Location& loc);
void PutByte(uint8 code);
void PutWord(uint16 code);
void CheckFrameIndex(int & reg, int & index, int size, int treg = 0);
void CheckFrameIndex(const InterInstruction * ins, int & reg, int & index, int size, int treg = 0);
void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction * ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh);
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction * ins, InterType type, int reg);
@ -311,9 +317,9 @@ public:
void CallAssembler(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void CallFunction(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
void ShiftRegisterLeft(InterCodeProcedure* proc, int reg, int shift);
void ShiftRegisterLeftByte(InterCodeProcedure* proc, int reg, int shift);
void ShiftRegisterLeftFromByte(InterCodeProcedure* proc, int reg, int shift, int max);
void ShiftRegisterLeft(InterCodeProcedure* proc, const InterInstruction* ins, int reg, int shift);
void ShiftRegisterLeftByte(InterCodeProcedure* proc, const InterInstruction* ins, int reg, int shift);
void ShiftRegisterLeftFromByte(InterCodeProcedure* proc, const InterInstruction* ins, int reg, int shift, int max);
int ShortMultiply(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins, int index, int mul);
int ShortSignedDivide(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins, const InterInstruction* sins, int mul);
@ -415,7 +421,7 @@ public:
bool JoinTAYARange(int from, int to);
bool PatchGlobalAdressSumYByX(int at, int reg, const NativeCodeInstruction& ains, int addr);
bool MergeXYSameValue(int from);
void InsertLoadYImmediate(int at, int val);
void InsertLoadYImmediate(const InterInstruction * iins, int at, int val);
int RetrieveAValue(int at) const;
int RetrieveXValue(int at) const;
int RetrieveYValue(int at) const;
@ -613,6 +619,8 @@ class NativeCodeProcedure
ExpandingArray<LinkerReference> mRelocations;
ExpandingArray< NativeCodeBasicBlock*> mBlocks;
ExpandingArray<CodeLocation> mCodeLocations;
void Compile(InterCodeProcedure* proc);
void Optimize(void);

View File

@ -211,6 +211,10 @@ int main2(int argc, const char** argv)
else
compiler->AddDefine(Ident::Unique(def), "");
}
else if (arg[1] == 'g')
{
compiler->mCompilerOptions |= COPT_DEBUGINFO;
}
else if (arg[1] == 'v')
{
compiler->mCompilerOptions |= COPT_VERBOSE;
@ -442,7 +446,7 @@ int main2(int argc, const char** argv)
}
else
{
printf("oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-tf=target] [-tm=machine] [-e] [-n] {-dSYMBOL[=value]} [-v] [-d64=diskname] {-f[z]=file.xxx} {source.c}\n");
printf("oscar64 {-i=includePath} [-o=output.prg] [-rt=runtime.c] [-tf=target] [-tm=machine] [-e] [-n] [-g] [-O(0|1|2|3)] {-dSYMBOL[=value]} [-v] [-d64=diskname] {-f[z]=file.xxx} {source.c}\n");
return 0;
}