Direct embedding of inline assembler in native code

This commit is contained in:
drmortalwombat 2021-09-28 18:35:23 +02:00
parent c4a5dafb69
commit e713dc5940
13 changed files with 200 additions and 116 deletions

View File

@ -20,7 +20,7 @@ int asum(int a, int b)
int bsum(int a, int b)
{
printf("Hello\n");
puts("Hello\n");
__asm
{

View File

@ -5,9 +5,9 @@ int kbhit(void)
__asm
{
lda $c6
sta 0x1b
sta accu
lda #0
sta 0x1c
sta accu + 1
}
}
@ -20,10 +20,10 @@ int getche(void)
cmp #0
beq L1
sta 0x1b
sta accu
jsr $ffd2
lda #0
sta 0x1c
sta accu + 1
}
}
@ -37,9 +37,9 @@ int getch(void)
cmp #0
beq L1
sta 0x1b
sta accu
lda #0
sta 0x1c
sta accu + 1
}
}
@ -90,9 +90,9 @@ int wherex(void)
__asm
{
lda $d3
sta 0x1b
sta accu
lda #0
sta 0x1c
sta accu + 1
}
}
@ -101,8 +101,8 @@ int wherey(void)
__asm
{
lda $d6
sta 0x1b
sta accu
lda #0
sta 0x1c
sta accu + 1
}
}

View File

@ -18,16 +18,16 @@ char getchar(void)
{
__asm {
jsr 0xffcf
sta 0x1b
sta accu
lda #0
sta 0x1c
sta accu + 1
}
}
void puts(const char * str)
{
__asm {
ldy #2
ldy #str
lda (fp), y
sta 0x02
iny

View File

@ -229,8 +229,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
LinkerReference rl;
rl.mOffset = block->mCode.Size();
rl.mLowByte = true;
rl.mHighByte = true;
rl.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
rl.mRefObject = mLinkerObject;
rl.mRefOffset = mValue;
block->mRelocations.Push(rl);
@ -278,8 +277,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
{
LinkerReference rl;
rl.mOffset = block->mCode.Size();
rl.mLowByte = true;
rl.mHighByte = true;
rl.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
rl.mRefObject = mLinkerObject;
rl.mRefOffset = mValue;
block->mRelocations.Push(rl);
@ -297,8 +295,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
{
LinkerReference rl;
rl.mOffset = block->mCode.Size();
rl.mLowByte = true;
rl.mHighByte = true;
rl.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
rl.mRefObject = mLinkerObject;
rl.mRefOffset = mValue;
block->mRelocations.Push(rl);
@ -463,8 +460,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
LinkerReference rl;
rl.mOffset = block->mCode.Size();
rl.mLowByte = true;
rl.mHighByte = true;
rl.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
rl.mRefObject = mLinkerObject;
rl.mRefOffset = 0;
block->mRelocations.Push(rl);
@ -2454,7 +2450,8 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
case IC_CALL:
CallFunction(iproc, ins);
break;
case IC_JSR:
case IC_CALL_NATIVE:
case IC_ASSEMBLER:
CallAssembler(iproc, ins);
break;
case IC_PUSH_FRAME:
@ -3001,7 +2998,7 @@ void ByteCodeBasicBlock::CopyCode(ByteCodeGenerator* generator, LinkerObject* li
LinkerReference rl = mRelocations[i];
rl.mObject = linkerObject;
rl.mOffset += mOffset;
generator->mLinker->AddReference(rl);
linkerObject->AddReference(rl);
}
end = mOffset + mCode.Size();

View File

@ -245,12 +245,11 @@ bool Compiler::GenerateCode(void)
LinkerReference lref;
lref.mObject = byteCodeObject;
lref.mLowByte = true;
lref.mHighByte = true;
lref.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
lref.mOffset = 2 * i;
lref.mRefObject = linkerObject;
lref.mRefOffset = offset;
mLinker->AddReference(lref);
byteCodeObject->AddReference(lref);
}
else
{
@ -261,6 +260,8 @@ bool Compiler::GenerateCode(void)
}
}
mLinker->CollectReferences();
mLinker->ReferenceObject(dcrtstart->mLinkerObject);
mLinker->ReferenceObject(byteCodeObject);

View File

@ -61,6 +61,7 @@ static const uint32 DTF_UPPER_BYTE = 0x00000400;
static const uint32 DTF_LOWER_BYTE = 0x00000800;
static const uint32 DTF_SECTION_START = 0x00001000;
static const uint32 DTF_SECTION_END = 0x00002000;
static const uint32 DTF_PARAM_PTR = 0x00004000;
class Declaration;

View File

@ -982,7 +982,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
}
break;
case IC_CALL:
case IC_JSR:
case IC_CALL_NATIVE:
FlushCallAliases();
break;
@ -1216,7 +1216,7 @@ void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTabl
bool HasSideEffect(InterCode code)
{
return code == IC_CALL || code == IC_JSR;
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER;
}
bool InterInstruction::RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps, int numStaticTemps)
@ -1277,7 +1277,7 @@ void InterInstruction::BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSe
if (mTTemp >= 0)
requiredTemps -= mTTemp;
if (mCode == IC_CALL || mCode == IC_JSR)
if (mCode == IC_CALL || mCode == IC_CALL_NATIVE)
callerSaveTemps |= requiredTemps;
if (mSTemp[0] >= 0) requiredTemps += mSTemp[0];
@ -1616,7 +1616,10 @@ void InterInstruction::Disassemble(FILE* file)
case IC_CALL:
fprintf(file, "CALL");
break;
case IC_JSR:
case IC_CALL_NATIVE:
fprintf(file, "CALLN");
break;
case IC_ASSEMBLER:
fprintf(file, "JSR");
break;
case IC_RETURN_VALUE:
@ -1810,7 +1813,8 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
switch (ins->mCode)
{
case IC_CALL:
case IC_JSR:
case IC_CALL_NATIVE:
case IC_ASSEMBLER:
if (ins->mSTemp[0] >= 0 && tvalue[ins->mSTemp[0]] && tvalue[ins->mSTemp[0]]->mCode == IC_CONSTANT)
{
ins->mMemory = tvalue[ins->mSTemp[0]]->mMemory;
@ -2938,7 +2942,7 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing
case IC_STORE:
case IC_LOAD:
case IC_JSR:
case IC_CALL_NATIVE:
if (mInstructions[i]->mMemory == IM_LOCAL)
{
localVars[mInstructions[i]->mVarIndex]->mUsed = true;
@ -2996,7 +3000,7 @@ bool InterCodeBasicBlock::IsLeafProcedure(void)
mVisited = true;
for (i = 0; i < mInstructions.Size(); i++)
if (mInstructions[i]->mCode == IC_CALL || mInstructions[i]->mCode == IC_JSR)
if (mInstructions[i]->mCode == IC_CALL || mInstructions[i]->mCode == IC_CALL_NATIVE)
return false;
if (mTrueJump && !mTrueJump->IsLeafProcedure())
@ -3015,7 +3019,7 @@ static bool CanBypassLoad(const InterInstruction * lins, const InterInstruction
return false;
// Side effects
if (bins->mCode == IC_CALL || bins->mCode == IC_JSR)
if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER)
return false;
// True data dependency
@ -3057,7 +3061,7 @@ static bool CanBypassStore(const InterInstruction * sins, const InterInstruction
return false;
// Side effects
if (bins->mCode == IC_CALL || bins->mCode == IC_JSR)
if (bins->mCode == IC_CALL || bins->mCode == IC_CALL_NATIVE || bins->mCode == IC_ASSEMBLER)
return false;
// True data dependency
@ -3431,7 +3435,8 @@ void InterCodeBasicBlock::CollectVariables(GrowingVariableArray& globalVars, Gro
case IC_STORE:
case IC_LOAD:
case IC_CONSTANT:
case IC_JSR:
case IC_CALL_NATIVE:
case IC_ASSEMBLER:
if (mInstructions[i]->mMemory == IM_LOCAL)
{
int varIndex = mInstructions[i]->mVarIndex;

View File

@ -29,10 +29,11 @@ enum InterCode
IC_PUSH_FRAME,
IC_POP_FRAME,
IC_CALL,
IC_JSR,
IC_CALL_NATIVE,
IC_RETURN_VALUE,
IC_RETURN_STRUCT,
IC_RETURN
IC_RETURN,
IC_ASSEMBLER
};
enum InterType

View File

@ -259,11 +259,13 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = aexp->mFlags & DTF_UPPER_BYTE;
ref.mLowByte = !(aexp->mFlags & DTF_UPPER_BYTE);
if (aexp->mFlags & DTF_UPPER_BYTE)
ref.mFlags = LREF_HIGHBYTE;
else
ref.mFlags = LREF_LOWBYTE;
ref.mRefObject = aexp->mBase->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset + aexp->mBase->mInteger;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
offset += 1;
}
@ -276,11 +278,13 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = aexp->mFlags & DTF_UPPER_BYTE;
ref.mLowByte = !(aexp->mFlags & DTF_UPPER_BYTE);
if (aexp->mFlags & DTF_UPPER_BYTE)
ref.mFlags = LREF_HIGHBYTE;
else
ref.mFlags = LREF_LOWBYTE;
ref.mRefObject = aexp->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
offset += 1;
}
@ -298,11 +302,13 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = aexp->mFlags & DTF_UPPER_BYTE;
ref.mLowByte = !(aexp->mFlags & DTF_UPPER_BYTE);
if (aexp->mFlags & DTF_UPPER_BYTE)
ref.mFlags = LREF_HIGHBYTE;
else
ref.mFlags = LREF_LOWBYTE;
ref.mRefObject = aexp->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
offset += 1;
}
@ -313,7 +319,20 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
case ASMIM_ZERO_PAGE_X:
case ASMIM_INDIRECT_X:
case ASMIM_INDIRECT_Y:
d[offset++] = aexp->mInteger;
if (aexp->mFlags & DTF_PARAM_PTR)
{
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mFlags = LREF_PARAM_PTR;
ref.mRefObject = dec->mLinkerObject;
ref.mRefOffset = 0;
dec->mLinkerObject->AddReference(ref);
offset += 1;
}
else
d[offset++] = aexp->mInteger;
break;
case ASMIM_ABSOLUTE:
case ASMIM_INDIRECT:
@ -334,11 +353,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = aexp->mBase->mLinkerObject;
ref.mRefOffset = aexp->mInteger;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
}
else
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined label");
@ -353,11 +371,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = aexp->mBase->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset + aexp->mBase->mInteger;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
offset += 2;
}
@ -369,11 +386,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = aexp->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
offset += 2;
}
@ -386,11 +402,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = aexp->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
offset += 2;
}
@ -404,11 +419,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = aexp->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
offset += 2;
}
@ -424,11 +438,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = aexp->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
offset += 2;
}
@ -443,11 +456,10 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression * e
LinkerReference ref;
ref.mObject = dec->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = aexp->mBase->mLinkerObject;
ref.mRefOffset = aexp->mOffset;
mLinker->AddReference(ref);
dec->mLinkerObject->AddReference(ref);
offset += 2;
}
@ -1560,7 +1572,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction * cins = new InterInstruction();
if (exp->mLeft->mDecValue && exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
cins->mCode = IC_JSR;
cins->mCode = IC_CALL_NATIVE;
else
cins->mCode = IC_CALL;
cins->mSType[0] = IT_POINTER;
@ -1593,6 +1605,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (block)
{
dec->mLinkerObject->mFlags |= LOBJF_INLINE;
InterInstruction* ins = new InterInstruction();
ins->mCode = IC_CONSTANT;
ins->mTType = IT_POINTER;
@ -1605,7 +1619,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block->Append(ins);
InterInstruction * jins = new InterInstruction();
jins->mCode = IC_JSR;
jins->mCode = IC_ASSEMBLER;
jins->mSType[0] = IT_POINTER;
jins->mSTemp[0] = ins->mTTemp;
@ -2161,11 +2175,10 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
LinkerReference ref;
ref.mObject = variable->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = data->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
variable->mLinkerObject->AddReference(ref);
}
else if (data->mType == DT_CONST_FUNCTION)
{
@ -2178,11 +2191,10 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
LinkerReference ref;
ref.mObject = variable->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
ref.mRefObject = data->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
variable->mLinkerObject->AddReference(ref);
}
else if (data->mType == DT_CONST_POINTER)
{
@ -2192,8 +2204,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
LinkerReference ref;
ref.mObject = variable->mLinkerObject;
ref.mOffset = offset;
ref.mHighByte = true;
ref.mLowByte = true;
ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
switch (dec->mType)
{
@ -2214,7 +2225,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
ref.mRefObject = dec->mLinkerObject;
ref.mRefOffset = 0;
mLinker->AddReference(ref);
variable->mLinkerObject->AddReference(ref);
break;
}
}

View File

@ -11,6 +11,22 @@ LinkerSection::LinkerSection(void)
: mObjects(nullptr)
{}
LinkerObject::LinkerObject(void)
: mReferences(nullptr)
{}
LinkerObject::~LinkerObject(void)
{
}
void LinkerObject::AddReference(const LinkerReference& ref)
{
LinkerReference* nref = new LinkerReference(ref);
mReferences.Push(nref);
}
void LinkerObject::AddData(const uint8* data, int size)
{
mSize = size;
@ -105,24 +121,27 @@ LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, L
obj->mIdent = ident;
obj->mSection = section;
obj->mProc = nullptr;
obj->mReferenced = false;
obj->mPlaced = false;
obj->mFlags = 0;
section->mObjects.Push(obj);
mObjects.Push(obj);
return obj;
}
void Linker::AddReference(const LinkerReference& ref)
void Linker::CollectReferences(void)
{
LinkerReference* nref = new LinkerReference(ref);
mReferences.Push(nref);
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* lobj(mObjects[i]);
for (int j = 0; j < lobj->mReferences.Size(); j++)
mReferences.Push(lobj->mReferences[j]);
}
}
void Linker::ReferenceObject(LinkerObject* obj)
{
if (!obj->mReferenced)
if (!(obj->mFlags & LOBJF_REFERENCED))
{
obj->mReferenced = true;
obj->mFlags |= LOBJF_REFERENCED;
for (int i = 0; i < mReferences.Size(); i++)
{
LinkerReference* ref = mReferences[i];
@ -155,9 +174,9 @@ void Linker::Link(void)
for (int k = 0; k < lsec->mObjects.Size(); k++)
{
LinkerObject* lobj = lsec->mObjects[k];
if (lobj->mReferenced && !lobj->mPlaced && lrgn->mStart + lrgn->mUsed + lobj->mSize <= lrgn->mEnd)
if ((lobj->mFlags & LOBJF_REFERENCED) && !(lobj->mFlags & LOBJF_PLACED) && lrgn->mStart + lrgn->mUsed + lobj->mSize <= lrgn->mEnd)
{
lobj->mPlaced = true;
lobj->mFlags |= LOBJF_PLACED;
lobj->mAddress = lrgn->mStart + lrgn->mUsed;
lrgn->mUsed += lobj->mSize;
@ -226,7 +245,7 @@ void Linker::Link(void)
obj->mAddress = obj->mSection->mStart;
else if (obj->mType == LOT_SECTION_END)
obj->mAddress = obj->mSection->mEnd;
else if (obj->mReferenced)
else if (obj->mFlags & LOBJF_REFERENCED)
{
memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize);
}
@ -236,17 +255,24 @@ void Linker::Link(void)
{
LinkerReference* ref = mReferences[i];
LinkerObject* obj = ref->mObject;
if (obj->mReferenced)
if (obj->mFlags & LOBJF_REFERENCED)
{
LinkerObject* robj = ref->mRefObject;
int raddr = robj->mAddress + ref->mRefOffset;
uint8* dp = mMemory + obj->mAddress + ref->mOffset;
if (ref->mLowByte)
if (ref->mFlags & LREF_LOWBYTE)
*dp++ = raddr & 0xff;
if (ref->mHighByte)
if (ref->mFlags & LREF_HIGHBYTE)
*dp++ = (raddr >> 8) & 0xff;
if (ref->mFlags & LREF_PARAM_PTR)
{
if (obj->mFlags & LOBJF_NO_FRAME)
*dp++ = BC_REG_STACK;
else
*dp++ = BC_REG_LOCALS;
}
}
}
}
@ -295,7 +321,7 @@ bool Linker::WriteMapFile(const char* filename)
{
LinkerObject* obj = mObjects[i];
if (obj->mReferenced)
if (obj->mFlags & LOBJF_REFERENCED)
{
if (obj->mIdent)
fprintf(file, "%04x - %04x : %s, %s:%s\n", obj->mAddress, obj->mAddress + obj->mSize, obj->mIdent->mString, LinkerObjectTypeNames[obj->mType], obj->mSection->mIdent->mString);
@ -322,7 +348,7 @@ bool Linker::WriteAsmFile(const char* filename)
{
LinkerObject* obj = mObjects[i];
if (obj->mReferenced)
if (obj->mFlags & LOBJF_REFERENCED)
{
switch (obj->mType)
{

View File

@ -48,12 +48,16 @@ public:
LinkerRegion(void);
};
static const uint32 LREF_LOWBYTE = 0x00000001;
static const uint32 LREF_HIGHBYTE = 0x00000002;
static const uint32 LREF_PARAM_PTR = 0x00000004;
class LinkerReference
{
public:
LinkerObject* mObject, * mRefObject;
int mOffset, mRefOffset;
bool mLowByte, mHighByte;
uint32 mFlags;
};
class LinkerSection
@ -70,22 +74,34 @@ public:
LinkerSection(void);
};
static const uint32 LOBJF_REFERENCED = 0x00000001;
static const uint32 LOBJF_PLACED = 0x00000002;
static const uint32 LOBJF_NO_FRAME = 0x00000004;
static const uint32 LOBJF_INLINE = 0x00000008;
class LinkerObject
{
public:
Location mLocation;
const Ident* mIdent;
Location mLocation;
const Ident * mIdent;
LinkerObjectType mType;
int mID;
int mAddress;
int mSize;
LinkerSection* mSection;
uint8* mData;
int mID;
int mAddress;
int mSize;
LinkerSection * mSection;
uint8 * mData;
InterCodeProcedure* mProc;
bool mReferenced, mPlaced;
uint32 mFlags;
LinkerObject(void);
~LinkerObject(void);
void AddData(const uint8* data, int size);
uint8* AddSpace(int size);
GrowingArray<LinkerReference*> mReferences;
void AddReference(const LinkerReference& ref);
};
class Linker
@ -104,7 +120,7 @@ public:
LinkerObject * AddObject(const Location & location, const Ident* ident, LinkerSection * section, LinkerObjectType type);
void AddReference(const LinkerReference& ref);
// void AddReference(const LinkerReference& ref);
bool WritePrgFile(const char* filename);
bool WriteMapFile(const char* filename);
@ -120,6 +136,7 @@ public:
void ReferenceObject(LinkerObject* obj);
void CollectReferences(void);
void Link(void);
protected:
NativeCodeDisassembler mNativeDisassembler;

View File

@ -1923,6 +1923,23 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
{
if (mType == ASMIT_BYTE)
block->PutByte(mAddress);
else if (mType == ASMIT_JSR && (mLinkerObject->mFlags & LOBJF_INLINE))
{
int pos = block->mCode.Size();
for (int i = 0; i < mLinkerObject->mSize - 1; i++)
block->PutByte(mLinkerObject->mData[i]);
for (int i = 0; i < mLinkerObject->mReferences.Size(); i++)
{
LinkerReference rl = *(mLinkerObject->mReferences[i]);
rl.mOffset += pos;
if (rl.mRefObject == rl.mObject)
{
rl.mRefObject = nullptr;
rl.mRefOffset += pos;
}
block->mRelocations.Push(rl);
}
}
else
{
if (mMode == ASMIM_IMMEDIATE_ADDRESS)
@ -1947,8 +1964,11 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
{
LinkerReference rl;
rl.mOffset = block->mCode.Size();
rl.mLowByte = mFlags & NCIF_LOWER;
rl.mHighByte = mFlags & NCIF_UPPER;
rl.mFlags = 0;
if (mFlags & NCIF_LOWER)
rl.mFlags |= LREF_LOWBYTE;
if (mFlags & NCIF_UPPER)
rl.mFlags |= LREF_HIGHBYTE;
rl.mRefObject = mLinkerObject;
rl.mRefObject = mLinkerObject;
@ -1969,8 +1989,7 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
{
LinkerReference rl;
rl.mOffset = block->mCode.Size();
rl.mLowByte = true;
rl.mHighByte = true;
rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
rl.mRefObject = mLinkerObject;
rl.mRefOffset = mAddress;
block->mRelocations.Push(rl);
@ -2038,8 +2057,7 @@ int NativeCodeBasicBlock::PutJump(NativeCodeProcedure* proc, int offset)
LinkerReference rl;
rl.mObject = nullptr;
rl.mOffset = mCode.Size();
rl.mLowByte = true;
rl.mHighByte = true;
rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
rl.mRefObject = nullptr;
rl.mRefOffset = mOffset + mCode.Size() + offset - 1;
mRelocations.Push(rl);
@ -2065,8 +2083,7 @@ int NativeCodeBasicBlock::PutBranch(NativeCodeProcedure* proc, AsmInsType code,
LinkerReference rl;
rl.mObject = nullptr;
rl.mOffset = mCode.Size();
rl.mLowByte = true;
rl.mHighByte = true;
rl.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE;
rl.mRefObject = nullptr;
rl.mRefOffset = mOffset + mCode.Size() + offset - 3;
mRelocations.Push(rl);
@ -4596,6 +4613,9 @@ void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, NativeCodeProc
void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins)
{
if (ins->mCode == IC_ASSEMBLER && mNoFrame)
ins->mLinkerObject->mFlags |= LOBJF_NO_FRAME;
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, ins->mSIntConst[0], ins->mLinkerObject));
if (ins->mTTemp >= 0)
@ -6128,6 +6148,9 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mNoFrame = proc->mLocalSize == 0 && tempSave == 0 && proc->mLeafProcedure;
if (mNoFrame)
proc->mLinkerObject->mFlags |= LOBJF_NO_FRAME;
entryBlock = new NativeCodeBasicBlock();
mBlocks.Push(entryBlock);
entryBlock->mNoFrame = mNoFrame;
@ -6316,7 +6339,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
rl.mObject = proc->mLinkerObject;
if (!rl.mRefObject)
rl.mRefObject = proc->mLinkerObject;
mGenerator->mLinker->AddReference(rl);
proc->mLinkerObject->AddReference(rl);
}
}
@ -6493,7 +6516,8 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
case IC_CALL:
block->CallFunction(iproc, this, ins);
break;
case IC_JSR:
case IC_CALL_NATIVE:
case IC_ASSEMBLER:
block->CallAssembler(iproc, ins);
break;
case IC_PUSH_FRAME:

View File

@ -2117,6 +2117,7 @@ Expression* Parser::ParseAssembler(void)
decfp->mBase = TheUnsignedIntTypeDeclaration;
decfp->mSize = 2;
decfp->mInteger = BC_REG_LOCALS;
decfp->mFlags = DTF_PARAM_PTR;
mScope->Insert(decfp->mIdent, decfp);
Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);