Fix move of store abs cross function call

This commit is contained in:
drmortalwombat 2025-02-01 20:13:18 +01:00
parent d0b45fce78
commit e23d78eb86
3 changed files with 121 additions and 24 deletions

View File

@ -2008,6 +2008,8 @@ bool NativeCodeInstruction::UsesMemoryOf(const NativeCodeInstruction& ins) const
else
return false;
}
else if (mType == ASMIT_JSR)
return true;
else
return false;
@ -8821,6 +8823,22 @@ bool NativeCodeBasicBlock::CheckPredAccuStore(int reg)
return true;
}
bool NativeCodeBasicBlock::CheckIsInAccu(int reg)
{
int i = mIns.Size() - 1;
while (i > 0)
{
if (mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mAddress == reg &&
mIns[i - 1].mType == ASMIT_LDA && mIns[i - 1].mMode == ASMIM_ZERO_PAGE && mIns[i - 1].mAddress == BC_REG_ACCU)
return true;
if (mIns[i].ReferencesZeroPage(reg) || mIns[i].ReferencesZeroPage(BC_REG_ACCU))
return false;
i--;
}
return false;
}
void NativeCodeBasicBlock::ShiftRegisterRight(const InterInstruction* ins, int reg, int shift)
{
if (shift == 0)
@ -10851,9 +10869,18 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
{
if (ins->mOperator == IA_ADD)
mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED));
if (treg == BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] &&
((ins->mOperator == IA_AND && (ins->mSrc[1].mIntConst & 0xff) == 0xff) ||
(ins->mOperator == IA_OR && (ins->mSrc[1].mIntConst & 0xff) == 0x00)))
{
}
else
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg));
}
if (InterTypeSize[ins->mDst.mType] > 1)
{
if (ins->mDst.IsUByte())
@ -10885,9 +10912,18 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
{
if (ins->mOperator == IA_ADD)
mIns.Push(NativeCodeInstruction(ins, ASMIT_CLC, ASMIM_IMPLIED));
if (treg == BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] &&
((ins->mOperator == IA_AND && (ins->mSrc[0].mIntConst & 0xff) == 0xff) ||
(ins->mOperator == IA_OR && (ins->mSrc[0].mIntConst & 0xff) == 0x00)))
{
}
else
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, treg));
}
if (InterTypeSize[ins->mDst.mType] > 1)
{
if (ins->mDst.IsUByte())
@ -11173,6 +11209,16 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
reg = ShortMultiply(proc, nproc, ins, sins1, 1, int(ins->mSrc[0].mIntConst));
}
else if (ins->mOperator == IA_MUL && ins->mSrc[0].IsUByte())
{
if (!sins0 && !sins1 && ins->mSrc[1].IsUByte() && CheckIsInAccu(BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]))
{
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]));
}
else
{
if (sins1)
LoadValueToReg(proc, sins1, BC_REG_ACCU, nullptr, nullptr);
@ -11191,6 +11237,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
}
else
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
}
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("mul16by8")));
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER | NCIF_USE_CPU_REG_A));
@ -52356,6 +52403,40 @@ NativeCodeProcedure::~NativeCodeProcedure(void)
}
void NativeCodeProcedure::DisassembleDebug(const char* name)
{
#if 0
#ifdef _WIN32
FILE* file;
static bool initial = true;
if (!CheckFunc)
return;
if (!initial)
{
fopen_s(&file, "r:\\ntivdiss.txt", "a");
}
else
{
fopen_s(&file, "r:\\ntivdiss.txt", "w");
initial = false;
}
if (file)
{
fprintf(file, "--------------------------------------------------------------------\n");
fprintf(file, "%s : %s:%d\n", name, mLocation.mFileName, mLocation.mLine);
fprintf(file, "\n");
ResetVisited();
mEntryBlock->Disassemble(file);
fclose(file);
}
#endif
#endif
}
void NativeCodeProcedure::Disassemble(FILE* file)
{
@ -52576,7 +52657,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mInterProc->mLinkerObject->mNativeProc = this;
CheckFunc = !strcmp(mIdent->mString, "player_move");
CheckFunc = !strcmp(mIdent->mString, "renderTileScroll");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -53546,12 +53627,10 @@ void NativeCodeProcedure::Optimize(void)
CheckBlocks();
#if 1
ResetVisited();
if (mEntryBlock->PeepHoleOptimizer(step))
changed = true;
#endif
if (step == 2)
{
@ -54385,6 +54464,12 @@ void NativeCodeProcedure::Optimize(void)
mEntryBlock->CheckAsmCode();
#endif
#if 0
char fname[100];
sprintf_s(fname, "Optimize %d, %d", step, cnt);
DisassembleDebug(fname);
#endif
#if 1
if (cnt > 190)
{

View File

@ -422,6 +422,7 @@ public:
int ShortSignedDivide(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction* ins, const InterInstruction* sins, int mul);
bool CheckPredAccuStore(int reg);
bool CheckIsInAccu(int reg);
NumberSet mLocalRequiredRegs, mLocalProvidedRegs;
NumberSet mEntryRequiredRegs, mEntryProvidedRegs;
@ -865,6 +866,7 @@ class NativeCodeProcedure
ExpandingArray<CodeLocation> mCodeLocations;
void DisassembleDebug(const char* name);
void Disassemble(FILE* file);
void Compile(InterCodeProcedure* proc);

View File

@ -5409,7 +5409,10 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
ndec = pdec;
}
else if ((mCompilerOptions & COPT_CPLUSPLUS) || mScope->mLevel >= SLEVEL_FUNCTION)
{
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate variable declaration", ndec->mIdent);
mErrors->Error(pdec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
}
else
{
if (!ndec->mBase->IsSame(pdec->mBase))
@ -5421,7 +5424,11 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
pdec->mBase = ndec->mBase;
}
else
{
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs", ndec->mIdent);
mErrors->Error(pdec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
}
}
pdec->mSection = ndec->mSection;
@ -5429,7 +5436,10 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
pdec->mFlags |= ndec->mFlags & DTF_ZEROPAGE;
if (pdec->mValue)
{
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate variable declaration", ndec->mIdent);
mErrors->Error(pdec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
}
ndec = pdec;