Direct embedding of inline assembler in native code
This commit is contained in:
parent
c4a5dafb69
commit
e713dc5940
|
@ -20,7 +20,7 @@ int asum(int a, int b)
|
|||
|
||||
int bsum(int a, int b)
|
||||
{
|
||||
printf("Hello\n");
|
||||
puts("Hello\n");
|
||||
|
||||
__asm
|
||||
{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue