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) int bsum(int a, int b)
{ {
printf("Hello\n"); puts("Hello\n");
__asm __asm
{ {

View File

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

View File

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

View File

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

View File

@ -245,12 +245,11 @@ bool Compiler::GenerateCode(void)
LinkerReference lref; LinkerReference lref;
lref.mObject = byteCodeObject; lref.mObject = byteCodeObject;
lref.mLowByte = true; lref.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
lref.mHighByte = true;
lref.mOffset = 2 * i; lref.mOffset = 2 * i;
lref.mRefObject = linkerObject; lref.mRefObject = linkerObject;
lref.mRefOffset = offset; lref.mRefOffset = offset;
mLinker->AddReference(lref); byteCodeObject->AddReference(lref);
} }
else else
{ {
@ -261,6 +260,8 @@ bool Compiler::GenerateCode(void)
} }
} }
mLinker->CollectReferences();
mLinker->ReferenceObject(dcrtstart->mLinkerObject); mLinker->ReferenceObject(dcrtstart->mLinkerObject);
mLinker->ReferenceObject(byteCodeObject); 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_LOWER_BYTE = 0x00000800;
static const uint32 DTF_SECTION_START = 0x00001000; static const uint32 DTF_SECTION_START = 0x00001000;
static const uint32 DTF_SECTION_END = 0x00002000; static const uint32 DTF_SECTION_END = 0x00002000;
static const uint32 DTF_PARAM_PTR = 0x00004000;
class Declaration; class Declaration;

View File

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

View File

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

View File

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

View File

@ -11,6 +11,22 @@ LinkerSection::LinkerSection(void)
: mObjects(nullptr) : 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) void LinkerObject::AddData(const uint8* data, int size)
{ {
mSize = size; mSize = size;
@ -105,24 +121,27 @@ LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, L
obj->mIdent = ident; obj->mIdent = ident;
obj->mSection = section; obj->mSection = section;
obj->mProc = nullptr; obj->mProc = nullptr;
obj->mReferenced = false; obj->mFlags = 0;
obj->mPlaced = false;
section->mObjects.Push(obj); section->mObjects.Push(obj);
mObjects.Push(obj); mObjects.Push(obj);
return obj; return obj;
} }
void Linker::AddReference(const LinkerReference& ref) void Linker::CollectReferences(void)
{ {
LinkerReference* nref = new LinkerReference(ref); for (int i = 0; i < mObjects.Size(); i++)
mReferences.Push(nref); {
LinkerObject* lobj(mObjects[i]);
for (int j = 0; j < lobj->mReferences.Size(); j++)
mReferences.Push(lobj->mReferences[j]);
}
} }
void Linker::ReferenceObject(LinkerObject* obj) 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++) for (int i = 0; i < mReferences.Size(); i++)
{ {
LinkerReference* ref = mReferences[i]; LinkerReference* ref = mReferences[i];
@ -155,9 +174,9 @@ void Linker::Link(void)
for (int k = 0; k < lsec->mObjects.Size(); k++) for (int k = 0; k < lsec->mObjects.Size(); k++)
{ {
LinkerObject* lobj = lsec->mObjects[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; lobj->mAddress = lrgn->mStart + lrgn->mUsed;
lrgn->mUsed += lobj->mSize; lrgn->mUsed += lobj->mSize;
@ -226,7 +245,7 @@ void Linker::Link(void)
obj->mAddress = obj->mSection->mStart; obj->mAddress = obj->mSection->mStart;
else if (obj->mType == LOT_SECTION_END) else if (obj->mType == LOT_SECTION_END)
obj->mAddress = obj->mSection->mEnd; obj->mAddress = obj->mSection->mEnd;
else if (obj->mReferenced) else if (obj->mFlags & LOBJF_REFERENCED)
{ {
memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize); memcpy(mMemory + obj->mAddress, obj->mData, obj->mSize);
} }
@ -236,17 +255,24 @@ void Linker::Link(void)
{ {
LinkerReference* ref = mReferences[i]; LinkerReference* ref = mReferences[i];
LinkerObject* obj = ref->mObject; LinkerObject* obj = ref->mObject;
if (obj->mReferenced) if (obj->mFlags & LOBJF_REFERENCED)
{ {
LinkerObject* robj = ref->mRefObject; LinkerObject* robj = ref->mRefObject;
int raddr = robj->mAddress + ref->mRefOffset; int raddr = robj->mAddress + ref->mRefOffset;
uint8* dp = mMemory + obj->mAddress + ref->mOffset; uint8* dp = mMemory + obj->mAddress + ref->mOffset;
if (ref->mLowByte) if (ref->mFlags & LREF_LOWBYTE)
*dp++ = raddr & 0xff; *dp++ = raddr & 0xff;
if (ref->mHighByte) if (ref->mFlags & LREF_HIGHBYTE)
*dp++ = (raddr >> 8) & 0xff; *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]; LinkerObject* obj = mObjects[i];
if (obj->mReferenced) if (obj->mFlags & LOBJF_REFERENCED)
{ {
if (obj->mIdent) 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); 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]; LinkerObject* obj = mObjects[i];
if (obj->mReferenced) if (obj->mFlags & LOBJF_REFERENCED)
{ {
switch (obj->mType) switch (obj->mType)
{ {

View File

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

View File

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

View File

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