Add breakpoint intrinsic in oscar.h

This commit is contained in:
drmortalwombat 2024-08-09 18:05:44 +02:00
parent 932c7ec222
commit 8a6e3eb924
11 changed files with 83 additions and 5 deletions

View File

@ -4739,9 +4739,14 @@ __asm inp_free
#pragma bytecode(BC_FREE, inp_free)
__asm breakpoint
{
rts
}
#pragma runtime(malloc, malloc)
#pragma runtime(free, free)
#pragma runtime(breakpoint, breakpoint)
#if 0

View File

@ -11,6 +11,13 @@ __native const char * oscar_expand_rle(char * dp, const char * sp);
// memory as buffer
__native const char * oscar_expand_lzo_buf(char * dp, const char * sp);
// Write a breakpoint instruction into the .lbl file for vice. This
// intrinsic function will change the behaviour of the optimizer to ensure
// that the breakpoint is not move around into wild places.
void breakpoint(void);
#pragma intrinsic(breakpoint)
#pragma compile("oscar.c")
#endif

View File

@ -961,6 +961,7 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("malloc"));
RegisterRuntime(loc, Ident::Unique("free"));
RegisterRuntime(loc, Ident::Unique("breakpoint"));
}
// Register extended byte code functions

View File

@ -1037,7 +1037,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
ex->mDecType = mDecType;
return ex;
}
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight->mType == EX_CONSTANT)
else if (mType == EX_CALL && mLeft->mType == EX_CONSTANT && (mLeft->mDecValue->mFlags & DTF_INTRINSIC) && mRight && mRight->mType == EX_CONSTANT)
{
Declaration* decf = mLeft->mDecValue, * decp = mRight->mDecValue;
const Ident* iname = decf->mQualIdent;

View File

@ -1698,12 +1698,12 @@ void ValueSet::InsertValue(InterInstruction * ins)
static bool HasSideEffect(InterCode code)
{
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH /* || code == IC_MALLOC || code == IC_FREE */;
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH || code == IC_BREAKPOINT;/* || code == IC_MALLOC || code == IC_FREE */;
}
static bool IsObservable(InterCode code)
{
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_FILL || code == IC_MALLOC || code == IC_FREE;
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_FILL || code == IC_MALLOC || code == IC_FREE || code == IC_BREAKPOINT;
}
static bool IsMoveable(InterCode code)
@ -5389,6 +5389,9 @@ void InterInstruction::Disassemble(FILE* file, InterCodeProcedure* proc)
case IC_UNREACHABLE:
fprintf(file, "UNREACHABLE");
break;
case IC_BREAKPOINT:
fprintf(file, "BREAKPOINT");
break;
}
static char typechars[] = "NBCILFP";

View File

@ -42,7 +42,8 @@ enum InterCode
IC_JUMPF,
IC_SELECT,
IC_DISPATCH,
IC_UNREACHABLE
IC_UNREACHABLE,
IC_BREAKPOINT
};
enum InterType

View File

@ -3436,6 +3436,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else if (!strcmp(iname->mString, "exp"))
{
}
else if (!strcmp(iname->mString, "breakpoint"))
{
InterInstruction* ins = new InterInstruction(MapLocation(exp, inlineMapper), IC_BREAKPOINT);
ins->mNumOperands = 0;
block->Append(ins);
return ExValue(TheVoidTypeDeclaration, 0);
}
else if (!strcmp(iname->mString, "malloc"))
{
vr = TranslateExpression(procType, proc, block, exp->mRight, destack, gotos, breakBlock, continueBlock, inlineMapper);

View File

@ -137,7 +137,7 @@ LinkerOverlay::~LinkerOverlay(void)
}
Linker::Linker(Errors* errors)
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr), mOverlays(nullptr), mCompilerOptions(COPT_DEFAULT)
: mErrors(errors), mSections(nullptr), mReferences(nullptr), mObjects(nullptr), mRegions(nullptr), mOverlays(nullptr), mBreakpoints(0), mCompilerOptions(COPT_DEFAULT)
{
for (int i = 0; i < 64; i++)
{
@ -850,6 +850,32 @@ void Linker::CopyObjects(bool inlays)
}
}
void Linker::CollectBreakpoints(void)
{
for (int i = 0; i < mReferences.Size(); i++)
{
LinkerReference* ref = mReferences[i];
if (ref->mFlags & LREF_BREAKPOINT)
{
LinkerObject* obj = ref->mObject;
if (obj->mFlags & LOBJF_REFERENCED)
{
if (obj->mRegion)
{
if (obj->mRegion->mCartridgeBanks)
{
}
else
{
mBreakpoints.Push(obj->mAddress + ref->mOffset);
}
}
}
}
}
}
void Linker::PatchReferences(bool inlays)
{
for (int i = 0; i < mReferences.Size(); i++)
@ -1119,6 +1145,7 @@ void Linker::Link(void)
CopyObjects(false);
PatchReferences(false);
CollectBreakpoints();
for (int i = 0; i < mObjects.Size(); i++)
{
@ -1866,6 +1893,11 @@ bool Linker::WriteLblFile(const char* filename)
}
}
for (int i = 0; i < mBreakpoints.Size(); i++)
{
fprintf(file, "break %04x\n", mBreakpoints[i]);
}
fclose(file);
return true;

View File

@ -110,6 +110,7 @@ static const uint32 LREF_HIGHBYTE = 0x00000002;
static const uint32 LREF_TEMPORARY = 0x00000004;
static const uint32 LREF_INBLOCK = 0x00000008;
static const uint32 LREF_LOWBYTE_OFFSET = 0x00000010;
static const uint32 LREF_BREAKPOINT = 0x00000020;
class LinkerReference
{
@ -292,6 +293,7 @@ public:
GrowingArray<LinkerSection*> mSections;
GrowingArray<LinkerObject*> mObjects;
GrowingArray<LinkerOverlay*> mOverlays;
GrowingArray<uint32> mBreakpoints;
uint8 mMemory[0x10000], mWorkspace[0x10000];
uint8 mCartridge[64][0x10000];
@ -312,6 +314,7 @@ public:
void CopyObjects(bool inlays);
void PlaceObjects(bool retry);
void Link(void);
void CollectBreakpoints(void);
protected:
NativeCodeDisassembler mNativeDisassembler;
ByteCodeDisassembler mByteCodeDisassembler;

View File

@ -4884,6 +4884,17 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
if (mType == ASMIT_BYTE)
block->PutByte(mAddress);
else if (mType == ASMIT_JSR && (mFlags & NCIF_BREAKPOINT))
{
LinkerReference rl;
rl.mOffset = block->mCode.Size();
rl.mRefObject = nullptr;
rl.mRefOffset = 0;
rl.mFlags = LREF_BREAKPOINT;
block->mRelocations.Push(rl);
}
else if (mType == ASMIT_JSR && mLinkerObject && (mLinkerObject->mFlags & LOBJF_INLINE))
{
int pos = block->mCode.Size();
@ -52564,6 +52575,11 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
case IC_FREE:
block->CallFree(iproc, ins, this);
break;
case IC_BREAKPOINT:
{
NativeCodeGenerator::Runtime& frt(mGenerator->ResolveRuntime(Ident::Unique("breakpoint")));
block->mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_LOWER | NCIF_UPPER | NCIF_VOLATILE | NCIF_BREAKPOINT));
} break;
case IC_LOAD_TEMPORARY:
{

View File

@ -133,6 +133,8 @@ static const uint32 NCIF_USE_ZP_32_X = 0x00008000;
static const uint32 NICF_USE_ZP_ADDR = 0x00010000;
static const uint32 NICF_USE_WORKREGS = 0x00020000;
static const uint32 NCIF_BREAKPOINT = 0x00040000;
class NativeCodeInstruction
{
public: