From e713dc5940f46cb293fccf669af1ded4218a8744 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Tue, 28 Sep 2021 18:35:23 +0200 Subject: [PATCH] Direct embedding of inline assembler in native code --- autotest/asmtest.c | 2 +- include/conio.c | 20 +++---- include/stdio.c | 6 +-- oscar64/ByteCodeGenerator.cpp | 17 +++--- oscar64/Compiler.cpp | 7 +-- oscar64/Declaration.h | 1 + oscar64/InterCode.cpp | 25 +++++---- oscar64/InterCode.h | 5 +- oscar64/InterCodeGenerator.cpp | 95 ++++++++++++++++++--------------- oscar64/Linker.cpp | 56 +++++++++++++------ oscar64/Linker.h | 37 +++++++++---- oscar64/NativeCodeGenerator.cpp | 44 +++++++++++---- oscar64/Parser.cpp | 1 + 13 files changed, 200 insertions(+), 116 deletions(-) diff --git a/autotest/asmtest.c b/autotest/asmtest.c index fb3c0d6..6161875 100644 --- a/autotest/asmtest.c +++ b/autotest/asmtest.c @@ -20,7 +20,7 @@ int asum(int a, int b) int bsum(int a, int b) { - printf("Hello\n"); + puts("Hello\n"); __asm { diff --git a/include/conio.c b/include/conio.c index 17ce854..921a868 100644 --- a/include/conio.c +++ b/include/conio.c @@ -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 } } diff --git a/include/stdio.c b/include/stdio.c index a76b7c6..e052695 100644 --- a/include/stdio.c +++ b/include/stdio.c @@ -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 diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index ba59872..3fc5e19 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -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(); diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index 960295a..ffd2d70 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -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); diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index ff1b966..8e155d9 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -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; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 18594d6..f70a1ba 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -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; diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index c87225a..a542947 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -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 diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 21c03f0..ca8d460 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -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; } } diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index 97ab60d..d73ccef 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -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) { diff --git a/oscar64/Linker.h b/oscar64/Linker.h index fa52441..116df1a 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -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 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; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 716f70a..3aaa7fa 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -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: diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index eb44fb7..1caf5ee 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -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);