Fix inline mapper for inline assembler

This commit is contained in:
drmortalwombat 2024-05-19 19:11:48 +02:00
parent 4c0e737508
commit d79aae3078
5 changed files with 151 additions and 7 deletions

View File

@ -629,6 +629,26 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
{ {
return mLeft->mLeft; return mLeft->mLeft;
} }
#endif
#if 1
else if (mType == EX_PREFIX && mToken == TK_BINARY_AND &&
mLeft->mType == EX_QUALIFY &&
mLeft->mLeft->mType == EX_PREFIX && mLeft->mLeft->mToken == TK_MUL &&
mLeft->mLeft->mLeft->mType == EX_CONSTANT)
{
Expression* bex = mLeft->mLeft->mLeft;
if (bex->mDecValue->mType == DT_CONST_ADDRESS)
{
Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_ADDRESS);
dec->mBase = mDecType;
dec->mInteger = bex->mDecValue->mInteger + mLeft->mDecValue->mOffset;
ex->mDecValue = dec;
ex->mDecType = mDecType;
return ex;
}
return mLeft;
}
#endif #endif
else if (mType == EX_TYPECAST && mLeft->mType == EX_CONSTANT) else if (mType == EX_TYPECAST && mLeft->mType == EX_CONSTANT)
{ {
@ -664,7 +684,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio
ex->mDecType = mDecType; ex->mDecType = mDecType;
return ex; return ex;
} }
else if (mLeft->mDecValue->mType == DT_CONST_INTEGER) else if (mLeft->mDecValue->mType == DT_CONST_INTEGER || mLeft->mDecValue->mType == DT_CONST_ADDRESS)
{ {
int64 sval = 1ULL << (8 * mDecType->mSize); int64 sval = 1ULL << (8 * mDecType->mSize);
int64 v = mLeft->mDecValue->mInteger & (sval - 1); int64 v = mLeft->mDecValue->mInteger & (sval - 1);

View File

@ -4040,6 +4040,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
vins->mConst.mVarIndex = vdec->mVarIndex; vins->mConst.mVarIndex = vdec->mVarIndex;
vins->mConst.mOperandSize = vdec->mSize; vins->mConst.mOperandSize = vdec->mSize;
vins->mConst.mIntConst = vdec->mOffset; vins->mConst.mIntConst = vdec->mOffset;
if (inlineMapper)
vins->mConst.mVarIndex += inlineMapper->mVarIndex;
} }
block->Append(vins); block->Append(vins);

View File

@ -23662,6 +23662,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
{ {
if (mTrueJump->mEntryRequiredRegs[ins.mAddress] && !mFalseJump->mEntryRequiredRegs[ins.mAddress] && mTrueJump->mEntryBlocks.Size() == 1) if (mTrueJump->mEntryRequiredRegs[ins.mAddress] && !mFalseJump->mEntryRequiredRegs[ins.mAddress] && mTrueJump->mEntryBlocks.Size() == 1)
{ {
mIns[ns - 1].mLive |= LIVE_CPU_REG_A;
mTrueJump->mIns.Insert(0, ins); mTrueJump->mIns.Insert(0, ins);
mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_C | mIns[ns - 1].mLive; mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_C | mIns[ns - 1].mLive;
mIns.Remove(ns - 2); mIns.Remove(ns - 2);
@ -23672,6 +23673,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
} }
else if (mFalseJump->mEntryRequiredRegs[ins.mAddress] && !mTrueJump->mEntryRequiredRegs[ins.mAddress] && mFalseJump->mEntryBlocks.Size() == 1) else if (mFalseJump->mEntryRequiredRegs[ins.mAddress] && !mTrueJump->mEntryRequiredRegs[ins.mAddress] && mFalseJump->mEntryBlocks.Size() == 1)
{ {
mIns[ns - 1].mLive |= LIVE_CPU_REG_A;
mFalseJump->mIns.Insert(0, ins); mFalseJump->mIns.Insert(0, ins);
mFalseJump->mIns[0].mLive |= LIVE_CPU_REG_C | mIns[ns - 1].mLive; mFalseJump->mIns[0].mLive |= LIVE_CPU_REG_C | mIns[ns - 1].mLive;
mIns.Remove(ns - 2); mIns.Remove(ns - 2);
@ -28993,6 +28995,53 @@ bool NativeCodeBasicBlock::FindExternAddressSumY(int at, int reg, int& breg, int
} }
bool NativeCodeBasicBlock::FindLoadAddressSumY(int at, int reg, int& apos, int& ireg)
{
int j = at - 7;
while (j >= 0)
{
if (mIns[j + 0].mType == ASMIT_LDA && mIns[j + 0].mMode != ASMIM_ZERO_PAGE &&
mIns[j + 1].mType == ASMIT_CLC &&
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == mIns[j + 0].mMode &&
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
{
ireg = mIns[j + 2].mAddress;
int k = j + 7;
while (k < at)
{
if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress())
return false;
k++;
}
apos = j;
return true;
}
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1))
return false;
if (mIns[j + 6].mMode == ASMIM_INDIRECT_Y && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress + 1 == reg || mIns[j + 6].mAddress == reg + 1))
return false;
if (mIns[j + 6].mType == ASMIT_JSR)
return false;
j--;
}
return false;
}
bool NativeCodeBasicBlock::PatchLoadAddressSumY(int at, int reg, int apos, int ireg)
{
mIns[apos + 1].mType = ASMIT_NOP; mIns[apos + 1].mMode = ASMIM_IMPLIED;
mIns[apos + 2].mType = ASMIT_NOP; mIns[apos + 2].mMode = ASMIM_IMPLIED;
mIns[apos + 5].mType = ASMIT_NOP; mIns[apos + 5].mMode = ASMIM_IMPLIED;
return true;
}
bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg) bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg)
{ {
int j = at - 7; int j = at - 7;
@ -40934,6 +40983,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
CheckLive(); CheckLive();
#endif #endif
} }
else if (!(mIns[i + 0].mLive & LIVE_MEM) && FindLoadAddressSumY(i, sreg, apos, ireg))
{
#if 1
RepairLoadYImmediate(i, 0);
PatchLoadAddressSumY(i, sreg, apos, ireg);
mIns.Insert(i + 0, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM;
mIns[i + 1].mFlags &= ~NCIF_YZERO;
progress = true;
CheckLive();
#endif
}
#if 1 #if 1
@ -41944,9 +42008,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
#if 1 #if 1
if (i + 2 < mIns.Size()) if (i + 2 < mIns.Size())
{ {
// NativeCodeInstruction i0 = mIns[i]; #if _DEBUG
// NativeCodeInstruction i1 = mIns[i + 1]; NativeCodeInstruction i0 = mIns[i];
// NativeCodeInstruction i2 = mIns[i + 2]; NativeCodeInstruction i1 = mIns[i + 1];
NativeCodeInstruction i2 = mIns[i + 2];
#endif
if (mIns[i].mType == ASMIT_LDA && mIns[i + 2].mType == ASMIT_LDA && (mIns[i + 1].mType == ASMIT_CLC || mIns[i + 1].mType == ASMIT_SEC)) if (mIns[i].mType == ASMIT_LDA && mIns[i + 2].mType == ASMIT_LDA && (mIns[i + 1].mType == ASMIT_CLC || mIns[i + 1].mType == ASMIT_SEC))
{ {
@ -43200,6 +43266,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2] = mIns[i + 1]; mIns[i + 2] = mIns[i + 1];
mIns[i + 0].mType = ASMIT_TXA; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_A; mIns[i + 0].mType = ASMIT_TXA; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mType = ASMIT_TAY; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_Y; mIns[i + 1].mType = ASMIT_TAY; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
if (mIns[i + 2].ReferencesXReg())
mIns[i + 1].mLive |= LIVE_CPU_REG_X;
mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
progress = true; progress = true;
} }
@ -44430,6 +44499,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mType = ASMIT_EOR; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 0xff; mIns[i + 2].mType = ASMIT_EOR; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 0xff;
mIns[i + 3].mType = ASMIT_ADC; mIns[i + 3].mType = ASMIT_ADC;
if (mIns[i + 3].ReferencesYReg())
mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
if (mIns[i + 3].ReferencesXReg())
mIns[i + 2].mLive |= LIVE_CPU_REG_X;
mIns[i + 0].mLive |= LIVE_CPU_REG_A; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mLive |= LIVE_CPU_REG_A; mIns[i + 1].mLive |= LIVE_CPU_REG_A;
@ -44446,6 +44520,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 1].mType = ASMIT_EOR; mIns[i + 1].mMode = ASMIM_IMMEDIATE; mIns[i + 1].mAddress = 0xff; mIns[i + 1].mType = ASMIT_EOR; mIns[i + 1].mMode = ASMIM_IMMEDIATE; mIns[i + 1].mAddress = 0xff;
mIns[i + 3].mType = ASMIT_ADC; mIns[i + 3].mType = ASMIT_ADC;
if (mIns[i + 3].ReferencesYReg())
{
mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
}
if (mIns[i + 3].ReferencesXReg())
{
mIns[i + 1].mLive |= LIVE_CPU_REG_X;
mIns[i + 2].mLive |= LIVE_CPU_REG_X;
}
mIns[i + 0].mLive |= LIVE_CPU_REG_A; mIns[i + 0].mLive |= LIVE_CPU_REG_A;
mIns[i + 1].mLive |= LIVE_CPU_REG_A; mIns[i + 1].mLive |= LIVE_CPU_REG_A;
@ -47750,7 +47835,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "window_mask3"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "enemies_move");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];
@ -48696,7 +48781,6 @@ void NativeCodeProcedure::Optimize(void)
} }
if (step > 2 && !changed) if (step > 2 && !changed)
{ {
ResetVisited(); ResetVisited();
@ -49117,7 +49201,6 @@ void NativeCodeProcedure::Optimize(void)
CheckBlocks(); CheckBlocks();
#if 1 #if 1
if (step == 8) if (step == 8)
{ {
@ -49147,6 +49230,7 @@ void NativeCodeProcedure::Optimize(void)
if (mEntryBlock->CrossBlock16BitFlood(this)) if (mEntryBlock->CrossBlock16BitFlood(this))
changed = true; changed = true;
} }
#if 1 #if 1
if (step >= 7) if (step >= 7)
{ {
@ -49159,6 +49243,7 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
#endif #endif
#if _DEBUG #if _DEBUG
ResetVisited(); ResetVisited();
mEntryBlock->CheckAsmCode(); mEntryBlock->CheckAsmCode();

View File

@ -443,6 +443,10 @@ public:
bool PatchDirectAddressSumY(int at, int reg, int apos, int breg); bool PatchDirectAddressSumY(int at, int reg, int apos, int breg);
bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg); bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg);
bool PatchAddressSumY(int at, int reg, int apos, int breg, int ireg); bool PatchAddressSumY(int at, int reg, int apos, int breg, int ireg);
bool FindLoadAddressSumY(int at, int reg, int& apos, int& ireg);
bool PatchLoadAddressSumY(int at, int reg, int apos, int ireg);
bool FindGlobalAddress(int at, int reg, int& apos); bool FindGlobalAddress(int at, int reg, int& apos);
bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags, int & addr); bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags, int & addr);
bool FindExternAddressSumY(int at, int reg, int& breg, int& ireg); bool FindExternAddressSumY(int at, int reg, int& breg, int& ireg);

View File

@ -10367,6 +10367,39 @@ Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
{ {
exp->mDecType = dec->mBase; exp->mDecType = dec->mBase;
} }
else if (dec->mType == DT_TYPE_STRUCT)
{
mScanner->NextToken();
int offset = 0;
while (dec->mType == DT_TYPE_STRUCT && ConsumeTokenIf(TK_COLCOLON))
{
if (mScanner->mToken == TK_IDENT)
{
Declaration* edec = dec->mScope->Lookup(mScanner->mTokenIdent);
if (edec)
{
offset += edec->mOffset;
dec = edec->mBase;
}
else
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Struct member not found", mScanner->mTokenIdent);
mScanner->NextToken();
}
else
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Identifier for qualification expected");
}
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
dec->mInteger = offset;
dec->mBase = TheUnsignedIntTypeDeclaration;
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
exp->mDecValue = dec;
exp->mDecType = dec->mBase;
return exp;
}
else else
exp->mDecType = TheUnsignedIntTypeDeclaration; exp->mDecType = TheUnsignedIntTypeDeclaration;
} }