Fix zero page parameter aliasing

This commit is contained in:
drmortalwombat 2024-09-23 21:27:27 +02:00
parent 21b5e75ddb
commit b1440a9b3f
5 changed files with 158 additions and 30 deletions

View File

@ -3889,6 +3889,7 @@ InterInstruction::InterInstruction(const Location& loc, InterCode code)
mSingleAssignment = false; mSingleAssignment = false;
mNoSideEffects = false; mNoSideEffects = false;
mConstExpr = false; mConstExpr = false;
mAliasing = false;
} }
static bool TypeInteger(InterType t) static bool TypeInteger(InterType t)
@ -5756,6 +5757,8 @@ void InterInstruction::Disassemble(FILE* file, InterCodeProcedure* proc)
fprintf(file, "C"); fprintf(file, "C");
if (mSingleAssignment) if (mSingleAssignment)
fprintf(file, "S"); fprintf(file, "S");
if (mAliasing)
fprintf(file, "A");
fprintf(file, "}\n"); fprintf(file, "}\n");
} }
} }
@ -20901,6 +20904,34 @@ void InterCodeBasicBlock::CheckValueReturn(void)
} }
} }
void InterCodeBasicBlock::MarkAliasing(const NumberSet& aliasedParams)
{
if (!mVisited)
{
mVisited = true;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins = mInstructions[i];
if (ins->mCode == IC_LOAD || ins->mCode == IC_COPY)
{
if ((ins->mSrc[0].mMemory == IM_PARAM || ins->mSrc[0].mMemory == IM_FPARAM) && aliasedParams[ins->mSrc[0].mVarIndex])
ins->mAliasing = true;
}
if (ins->mCode == IC_STORE || ins->mCode == IC_FILL || ins->mCode == IC_COPY)
{
if ((ins->mSrc[1].mMemory == IM_PARAM || ins->mSrc[1].mMemory == IM_FPARAM) && aliasedParams[ins->mSrc[1].mVarIndex])
ins->mAliasing = true;
}
}
if (mTrueJump) mTrueJump->MarkAliasing(aliasedParams);
if (mFalseJump) mFalseJump->MarkAliasing(aliasedParams);
}
}
void InterCodeBasicBlock::CollectGlobalReferences(NumberSet& referencedGlobals, NumberSet& modifiedGlobals, bool& storesIndirect, bool& loadsIndirect, bool& globalsChecked) void InterCodeBasicBlock::CollectGlobalReferences(NumberSet& referencedGlobals, NumberSet& modifiedGlobals, bool& storesIndirect, bool& loadsIndirect, bool& globalsChecked)
{ {
if (!mVisited) if (!mVisited)
@ -22454,7 +22485,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "main"); CheckFunc = !strcmp(mIdent->mString, "testD");
CheckCase = false; CheckCase = false;
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];
@ -23537,6 +23568,11 @@ void InterCodeProcedure::Close(void)
#endif #endif
ResetVisited(); ResetVisited();
mEntryBlock->CollectGlobalReferences(mReferencedGlobals, mModifiedGlobals, mStoresIndirect, mLoadsIndirect, mGlobalsChecked); mEntryBlock->CollectGlobalReferences(mReferencedGlobals, mModifiedGlobals, mStoresIndirect, mLoadsIndirect, mGlobalsChecked);
ResetVisited();
mEntryBlock->MarkAliasing(mParamAliasedSet);
DisassembleDebug("Marked Aliasing");
} }
void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc) void InterCodeProcedure::AddCalledFunction(InterCodeProcedure* proc)

View File

@ -317,7 +317,7 @@ public:
InterOperator mOperator; InterOperator mOperator;
int mNumOperands; int mNumOperands;
bool mInUse, mInvariant, mVolatile, mExpensive, mSingleAssignment, mNoSideEffects, mConstExpr, mRemove; bool mInUse, mInvariant, mVolatile, mExpensive, mSingleAssignment, mNoSideEffects, mConstExpr, mRemove, mAliasing;
InterInstruction(const Location& loc, InterCode code); InterInstruction(const Location& loc, InterCode code);
@ -671,6 +671,7 @@ public:
void CollectGlobalReferences(NumberSet& referencedGlobals, NumberSet& modifiedGlobals, bool & storesIndirect, bool & loadsIndirect, bool & globalsChecked); void CollectGlobalReferences(NumberSet& referencedGlobals, NumberSet& modifiedGlobals, bool & storesIndirect, bool & loadsIndirect, bool & globalsChecked);
void MarkAliasing(const NumberSet& aliasedParams);
}; };
class InterCodeProcedure class InterCodeProcedure

View File

@ -36,6 +36,7 @@ NativeRegisterData::NativeRegisterData(void)
void NativeRegisterData::Reset(void) void NativeRegisterData::Reset(void)
{ {
mFlags = 0;
mMode = NRDM_UNKNOWN; mMode = NRDM_UNKNOWN;
mValue = GlobalValueNumber++; mValue = GlobalValueNumber++;
} }
@ -45,6 +46,13 @@ void NativeRegisterData::ResetMask(void)
mMask = 0; mMask = 0;
} }
void NativeRegisterData::ResetAliasing(void)
{
if (mFlags & NCIF_ALIASING)
Reset();
}
bool NativeRegisterData::SameData(const NativeCodeInstruction& ins) const bool NativeRegisterData::SameData(const NativeCodeInstruction& ins) const
{ {
if (ins.mMode == ASMIM_ZERO_PAGE) if (ins.mMode == ASMIM_ZERO_PAGE)
@ -139,6 +147,8 @@ void NativeRegisterDataSet::ResetCall(const NativeCodeInstruction& ins, int fast
if (!(ins.mFlags & NCIF_RUNTIME) || (ins.mFlags & NCIF_FEXEC)) if (!(ins.mFlags & NCIF_RUNTIME) || (ins.mFlags & NCIF_FEXEC))
{ {
ResetAliasing();
if (ins.mLinkerObject && ins.mLinkerObject->mProc) if (ins.mLinkerObject && ins.mLinkerObject->mProc)
{ {
for (int i = BC_REG_TMP; i < BC_REG_TMP + ins.mLinkerObject->mProc->mCallerSavedTemps; i++) for (int i = BC_REG_TMP; i < BC_REG_TMP + ins.mLinkerObject->mProc->mCallerSavedTemps; i++)
@ -175,6 +185,12 @@ void NativeRegisterDataSet::ResetWorkRegs(void)
ResetZeroPageRange(BC_REG_WORK, 8); ResetZeroPageRange(BC_REG_WORK, 8);
} }
void NativeRegisterDataSet::ResetAliasing(void)
{
for (int i = 0; i < NUM_REGS; i++)
mRegs[i].ResetAliasing();
}
void NativeRegisterDataSet::ResetWorkMasks(void) void NativeRegisterDataSet::ResetWorkMasks(void)
{ {
mRegs[BC_REG_WORK_Y].ResetMask(); mRegs[BC_REG_WORK_Y].ResetMask();
@ -3867,6 +3883,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
{ {
data.mRegs[CPU_REG_A].mMode = NRDM_ZERO_PAGE; data.mRegs[CPU_REG_A].mMode = NRDM_ZERO_PAGE;
data.mRegs[CPU_REG_A].mValue = mAddress; data.mRegs[CPU_REG_A].mValue = mAddress;
data.mRegs[CPU_REG_A].mFlags = mFlags;
} }
} }
break; break;
@ -4058,6 +4075,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
{ {
data.mRegs[data.mRegs[CPU_REG_A].mValue].mMode = NRDM_ZERO_PAGE; data.mRegs[data.mRegs[CPU_REG_A].mValue].mMode = NRDM_ZERO_PAGE;
data.mRegs[data.mRegs[CPU_REG_A].mValue].mValue = mAddress; data.mRegs[data.mRegs[CPU_REG_A].mValue].mValue = mAddress;
data.mRegs[data.mRegs[CPU_REG_A].mValue].mFlags = mFlags;
data.mRegs[mAddress].Reset(); data.mRegs[mAddress].Reset();
} }
else else
@ -4065,6 +4083,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
{ {
data.mRegs[mAddress].mMode = NRDM_ZERO_PAGE; data.mRegs[mAddress].mMode = NRDM_ZERO_PAGE;
data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_A].mValue; data.mRegs[mAddress].mValue = data.mRegs[CPU_REG_A].mValue;
data.mRegs[mAddress].mFlags = data.mRegs[CPU_REG_A].mFlags;
} }
} }
@ -5457,6 +5476,8 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
uint32 flags = NCIF_LOWER | NCIF_UPPER; uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (ins->mVolatile) if (ins->mVolatile)
flags |= NCIF_VOLATILE; flags |= NCIF_VOLATILE;
if (ins->mAliasing)
flags |= NCIF_ALIASING;
if (ins->mSrc[0].mType == IT_FLOAT) if (ins->mSrc[0].mType == IT_FLOAT)
{ {
@ -6338,6 +6359,8 @@ void NativeCodeBasicBlock::LoadByteIndexedValue(InterCodeProcedure* proc, const
uint32 flags = NCIF_LOWER | NCIF_UPPER; uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (rins->mVolatile) if (rins->mVolatile)
flags |= NCIF_VOLATILE; flags |= NCIF_VOLATILE;
if (rins->mAliasing)
flags |= NCIF_ALIASING;
for (int i = 0; i < InterTypeSize[rins->mDst.mType]; i++) for (int i = 0; i < InterTypeSize[rins->mDst.mType]; i++)
{ {
@ -6367,6 +6390,8 @@ void NativeCodeBasicBlock::StoreByteIndexedValue(InterCodeProcedure* proc, const
uint32 flags = NCIF_LOWER | NCIF_UPPER; uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (wins->mVolatile) if (wins->mVolatile)
flags |= NCIF_VOLATILE; flags |= NCIF_VOLATILE;
if (wins->mAliasing)
flags |= NCIF_ALIASING;
for (int i = 0; i < InterTypeSize[wins->mSrc[0].mType]; i++) for (int i = 0; i < InterTypeSize[wins->mSrc[0].mType]; i++)
{ {
@ -6389,6 +6414,8 @@ void NativeCodeBasicBlock::LoadAbsoluteByteIndexedValue(InterCodeProcedure* proc
uint32 flags = NCIF_LOWER | NCIF_UPPER; uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (rins->mVolatile) if (rins->mVolatile)
flags |= NCIF_VOLATILE; flags |= NCIF_VOLATILE;
if (rins->mAliasing)
flags |= NCIF_ALIASING;
for (int i = 0; i < InterTypeSize[rins->mDst.mType]; i++) for (int i = 0; i < InterTypeSize[rins->mDst.mType]; i++)
{ {
@ -6405,6 +6432,8 @@ void NativeCodeBasicBlock::StoreAbsoluteByteIndexedValue(InterCodeProcedure* pro
uint32 flags = NCIF_LOWER | NCIF_UPPER; uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (wins->mVolatile) if (wins->mVolatile)
flags |= NCIF_VOLATILE; flags |= NCIF_VOLATILE;
if (wins->mAliasing)
flags |= NCIF_ALIASING;
for (int i = 0; i < InterTypeSize[wins->mSrc[0].mType]; i++) for (int i = 0; i < InterTypeSize[wins->mSrc[0].mType]; i++)
{ {
@ -6427,6 +6456,8 @@ void NativeCodeBasicBlock::StoreByteOffsetIndexedValue(InterCodeProcedure* proc,
uint32 flags = NCIF_LOWER | NCIF_UPPER; uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (wins->mVolatile) if (wins->mVolatile)
flags |= NCIF_VOLATILE; flags |= NCIF_VOLATILE;
if (wins->mAliasing)
flags |= NCIF_ALIASING;
for (int i = 0; i < InterTypeSize[wins->mSrc[0].mType]; i++) for (int i = 0; i < InterTypeSize[wins->mSrc[0].mType]; i++)
{ {
@ -6449,12 +6480,16 @@ void NativeCodeBasicBlock::LoadStoreIndirectPair(InterCodeProcedure* proc, const
uint32 wflags0 = NCIF_LOWER | NCIF_UPPER; uint32 wflags0 = NCIF_LOWER | NCIF_UPPER;
if (wins0->mVolatile) if (wins0->mVolatile)
wflags0 |= NCIF_VOLATILE; wflags0 |= NCIF_VOLATILE;
if (wins0->mAliasing)
wflags0 |= NCIF_ALIASING;
int ireg1 = BC_REG_TMP + proc->mTempOffset[wins1->mSrc[1].mTemp]; int ireg1 = BC_REG_TMP + proc->mTempOffset[wins1->mSrc[1].mTemp];
int index1 = int(wins1->mSrc[1].mIntConst); int index1 = int(wins1->mSrc[1].mIntConst);
uint32 wflags1 = NCIF_LOWER | NCIF_UPPER; uint32 wflags1 = NCIF_LOWER | NCIF_UPPER;
if (wins1->mVolatile) if (wins1->mVolatile)
wflags1 |= NCIF_VOLATILE; wflags1 |= NCIF_VOLATILE;
if (wins1->mAliasing)
wflags1 |= NCIF_ALIASING;
CheckFrameIndex(wins0, ireg0, index0, 1, BC_REG_ADDR); CheckFrameIndex(wins0, ireg0, index0, 1, BC_REG_ADDR);
CheckFrameIndex(wins1, ireg1, index1, 1, BC_REG_ACCU); CheckFrameIndex(wins1, ireg1, index1, 1, BC_REG_ACCU);
@ -6481,6 +6516,8 @@ void NativeCodeBasicBlock::LoadStoreIndirectValue(InterCodeProcedure* proc, cons
uint32 rflags = NCIF_LOWER | NCIF_UPPER; uint32 rflags = NCIF_LOWER | NCIF_UPPER;
if (rins->mVolatile) if (rins->mVolatile)
rflags |= NCIF_VOLATILE; rflags |= NCIF_VOLATILE;
if (rins->mAliasing)
rflags |= NCIF_ALIASING;
switch (rins->mSrc[0].mMemory) switch (rins->mSrc[0].mMemory)
{ {
@ -6523,6 +6560,8 @@ void NativeCodeBasicBlock::LoadStoreIndirectValue(InterCodeProcedure* proc, cons
uint32 wflags = NCIF_LOWER | NCIF_UPPER; uint32 wflags = NCIF_LOWER | NCIF_UPPER;
if (wins->mVolatile) if (wins->mVolatile)
wflags |= NCIF_VOLATILE; wflags |= NCIF_VOLATILE;
if (wins->mAliasing)
wflags |= NCIF_ALIASING;
switch (wins->mSrc[1].mMemory) switch (wins->mSrc[1].mMemory)
{ {
@ -6593,10 +6632,14 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI
uint32 rflags = NCIF_LOWER | NCIF_UPPER; uint32 rflags = NCIF_LOWER | NCIF_UPPER;
if (rins->mVolatile) if (rins->mVolatile)
rflags |= NCIF_VOLATILE; rflags |= NCIF_VOLATILE;
if (rins->mAliasing)
rflags |= NCIF_ALIASING;
uint32 wflags = NCIF_LOWER | NCIF_UPPER; uint32 wflags = NCIF_LOWER | NCIF_UPPER;
if (wins->mVolatile) if (wins->mVolatile)
wflags |= NCIF_VOLATILE; wflags |= NCIF_VOLATILE;
if (wins->mAliasing)
wflags |= NCIF_ALIASING;
if (rins->mDst.mType == IT_FLOAT) if (rins->mDst.mType == IT_FLOAT)
@ -6901,10 +6944,15 @@ bool NativeCodeBasicBlock::LoadUnopStoreIndirectValue(InterCodeProcedure* proc,
uint32 rflags = NCIF_LOWER | NCIF_UPPER; uint32 rflags = NCIF_LOWER | NCIF_UPPER;
if (rins->mVolatile) if (rins->mVolatile)
rflags |= NCIF_VOLATILE; rflags |= NCIF_VOLATILE;
if (rins->mAliasing)
rflags |= NCIF_ALIASING;
uint32 wflags = NCIF_LOWER | NCIF_UPPER; uint32 wflags = NCIF_LOWER | NCIF_UPPER;
if (wins->mVolatile) if (wins->mVolatile)
wflags |= NCIF_VOLATILE; wflags |= NCIF_VOLATILE;
if (wins->mAliasing)
wflags |= NCIF_ALIASING;
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
@ -7040,10 +7088,14 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
uint32 rflags = NCIF_LOWER | NCIF_UPPER; uint32 rflags = NCIF_LOWER | NCIF_UPPER;
if (rins->mVolatile) if (rins->mVolatile)
rflags |= NCIF_VOLATILE; rflags |= NCIF_VOLATILE;
if (rins->mAliasing)
rflags |= NCIF_ALIASING;
uint32 wflags = NCIF_LOWER | NCIF_UPPER; uint32 wflags = NCIF_LOWER | NCIF_UPPER;
if (wins->mVolatile) if (wins->mVolatile)
wflags |= NCIF_VOLATILE; wflags |= NCIF_VOLATILE;
if (wins->mAliasing)
wflags |= NCIF_ALIASING;
if (ram == ASMIM_INDIRECT_Y && wam == ASMIM_INDIRECT_Y && rareg == wareg && rindex == windex) if (ram == ASMIM_INDIRECT_Y && wam == ASMIM_INDIRECT_Y && rareg == wareg && rindex == windex)
{ {
@ -7128,6 +7180,8 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
uint32 flags = NCIF_LOWER | NCIF_UPPER; uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (ins->mVolatile) if (ins->mVolatile)
flags |= NCIF_VOLATILE; flags |= NCIF_VOLATILE;
if (ins->mAliasing)
flags |= NCIF_ALIASING;
if (ins->mDst.mType == IT_FLOAT) if (ins->mDst.mType == IT_FLOAT)
{ {
@ -7159,13 +7213,13 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
} }
else if (ins->mSrc[0].mMemory == IM_FPARAM) else if (ins->mSrc[0].mMemory == IM_FPARAM)
{ {
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst, nullptr, flags));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 1)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 1, nullptr, flags));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 2)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 2, nullptr, flags));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 3)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 3, nullptr, flags));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
} }
else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM) else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM)
@ -7268,7 +7322,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
} }
else if (ins->mSrc[0].mMemory == IM_FPARAM) else if (ins->mSrc[0].mMemory == IM_FPARAM)
{ {
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst, nullptr, flags));
if (ainsl) if (ainsl)
{ {
if (ainsl->mType == ASMIT_ADC) if (ainsl->mType == ASMIT_ADC)
@ -7278,7 +7332,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
mIns.Push(*ainsl); mIns.Push(*ainsl);
} }
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + stride)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + stride, nullptr, flags));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
} }
@ -7362,7 +7416,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
} }
else if (ins->mSrc[0].mMemory == IM_FPARAM) else if (ins->mSrc[0].mMemory == IM_FPARAM)
{ {
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst, nullptr, flags));
} }
else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM) else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM)
{ {
@ -7434,7 +7488,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
} }
else if (ins->mSrc[0].mMemory == IM_FPARAM) else if (ins->mSrc[0].mMemory == IM_FPARAM)
{ {
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst, nullptr, flags));
if (ainsl) if (ainsl)
{ {
if (ainsl->mType == ASMIT_ADC) if (ainsl->mType == ASMIT_ADC)
@ -7444,7 +7498,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
mIns.Push(*ainsl); mIns.Push(*ainsl);
} }
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 1 * stride)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 1 * stride, nullptr, flags));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
} }
@ -7504,13 +7558,13 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
} }
else if (ins->mSrc[0].mMemory == IM_FPARAM) else if (ins->mSrc[0].mMemory == IM_FPARAM)
{ {
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst, nullptr, flags));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 1 * stride)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 1 * stride, nullptr, flags));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 2 * stride)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 2 * stride, nullptr, flags));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 3 * stride)); mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_FPARAMS + ins->mSrc[0].mVarIndex + ins->mSrc[0].mIntConst + 3 * stride, nullptr, flags));
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
} }
else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM) else if (ins->mSrc[0].mMemory == IM_LOCAL || ins->mSrc[0].mMemory == IM_PARAM)
@ -7628,6 +7682,8 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc,
uint32 flags = NCIF_LOWER | NCIF_UPPER; uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (ins->mVolatile) if (ins->mVolatile)
flags |= NCIF_VOLATILE; flags |= NCIF_VOLATILE;
if (ins->mAliasing)
flags |= NCIF_ALIASING;
if (sstride > 1 || dstride > 1) if (sstride > 1 || dstride > 1)
msize = 32; msize = 32;
@ -8122,6 +8178,8 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::FillValue(InterCodeProcedure* proc,
uint32 flags = NCIF_LOWER | NCIF_UPPER; uint32 flags = NCIF_LOWER | NCIF_UPPER;
if (ins->mVolatile) if (ins->mVolatile)
flags |= NCIF_VOLATILE; flags |= NCIF_VOLATILE;
if (ins->mAliasing)
flags |= NCIF_ALIASING;
if (dstride > 1) if (dstride > 1)
msize = 32; msize = 32;
@ -14714,6 +14772,9 @@ void NativeCodeBasicBlock::FindZeroPageAlias(const NumberSet& statics, NumberSet
accu = -1; accu = -1;
else if (mIns[i].ChangesAddress()) else if (mIns[i].ChangesAddress())
invalid += mIns[i].mAddress; invalid += mIns[i].mAddress;
if (mIns[i].mFlags & NCIF_ALIASING)
invalid += mIns[i].mAddress;
} }
else if (mIns[i].mType == ASMIT_JSR && (mIns[i].mFlags & NCIF_USE_ZP_32_X)) else if (mIns[i].mType == ASMIT_JSR && (mIns[i].mFlags & NCIF_USE_ZP_32_X))
{ {
@ -14831,7 +14892,7 @@ void NativeCodeBasicBlock::CollectZeroPageUsage(NumberSet& used, NumberSet &modi
{ {
case ASMIM_ZERO_PAGE: case ASMIM_ZERO_PAGE:
used += mIns[i].mAddress; used += mIns[i].mAddress;
if (mIns[i].ChangesAddress()) if (mIns[i].ChangesAddress() || (mIns[i].mFlags & NCIF_ALIASING))
modified += mIns[i].mAddress; modified += mIns[i].mAddress;
break; break;
case ASMIM_INDIRECT_Y: case ASMIM_INDIRECT_Y:
@ -28946,7 +29007,7 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(const NativeCodeBasicBl
{ {
NativeCodeInstruction& ins(mIns[at]); NativeCodeInstruction& ins(mIns[at]);
if (at + 6 < mIns.Size() && if (index && at + 6 < mIns.Size() &&
mIns[at + 0].mType == ASMIT_CLC && mIns[at + 0].mType == ASMIT_CLC &&
mIns[at + 1].mType == ASMIT_LDA && mIns[at + 1].mMode == ASMIM_ZERO_PAGE && mIns[at + 1].mAddress == reg && mIns[at + 1].mType == ASMIT_LDA && mIns[at + 1].mMode == ASMIM_ZERO_PAGE && mIns[at + 1].mAddress == reg &&
mIns[at + 2].mMode == ASMIM_IMMEDIATE && (mIns[at + 2].mType == ASMIT_ADC || mIns[at + 2].mType == ASMIT_ORA && mIns[at + 2].mAddress == 0) && mIns[at + 2].mMode == ASMIM_IMMEDIATE && (mIns[at + 2].mType == ASMIT_ADC || mIns[at + 2].mType == ASMIT_ORA && mIns[at + 2].mAddress == 0) &&
@ -28964,7 +29025,7 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(const NativeCodeBasicBl
; ;
else if (ins.mMode == ASMIM_ZERO_PAGE) else if (ins.mMode == ASMIM_ZERO_PAGE)
{ {
if (ins.mAddress == index && ins.ChangesAddress()) if (index && ins.mAddress == index && ins.ChangesAddress())
return false; return false;
else if (ins.mAddress == reg || ins.mAddress == reg + 1) else if (ins.mAddress == reg || ins.mAddress == reg + 1)
{ {
@ -28991,7 +29052,7 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(const NativeCodeBasicBl
yval = (yval - 1) & 255; yval = (yval - 1) & 255;
else if (ins.mType == ASMIT_JSR || ins.mType == ASMIT_RTS) else if (ins.mType == ASMIT_JSR || ins.mType == ASMIT_RTS)
{ {
if (ins.UsesZeroPage(reg) || ins.UsesZeroPage(reg + 1) || ins.ChangesZeroPage(index)) if (ins.UsesZeroPage(reg) || ins.UsesZeroPage(reg + 1) || (index && ins.ChangesZeroPage(index)))
return false; return false;
yval = -1; yval = -1;
} }
@ -29026,7 +29087,7 @@ bool NativeCodeBasicBlock::PatchGlobalAddressSumYPointer(const NativeCodeBasicBl
// assert(!(ins.mMode == ASMIM_ZERO_PAGE && (ins.mAddress == reg || ins.mAddress == reg + 1) && reg == index)); // assert(!(ins.mMode == ASMIM_ZERO_PAGE && (ins.mAddress == reg || ins.mAddress == reg + 1) && reg == index));
if (at + 6 < mIns.Size() && if (index && at + 6 < mIns.Size() &&
mIns[at + 0].mType == ASMIT_CLC && mIns[at + 0].mType == ASMIT_CLC &&
mIns[at + 1].mType == ASMIT_LDA && mIns[at + 1].mMode == ASMIM_ZERO_PAGE && mIns[at + 1].mAddress == reg && mIns[at + 1].mType == ASMIT_LDA && mIns[at + 1].mMode == ASMIM_ZERO_PAGE && mIns[at + 1].mAddress == reg &&
mIns[at + 2].mMode == ASMIM_IMMEDIATE && (mIns[at + 2].mType == ASMIT_ADC || mIns[at + 2].mType == ASMIT_ORA && mIns[at + 2].mAddress == 0) && mIns[at + 2].mMode == ASMIM_IMMEDIATE && (mIns[at + 2].mType == ASMIT_ADC || mIns[at + 2].mType == ASMIT_ORA && mIns[at + 2].mAddress == 0) &&
@ -29076,10 +29137,17 @@ bool NativeCodeBasicBlock::PatchGlobalAddressSumYPointer(const NativeCodeBasicBl
const InterInstruction* iins = ins.mIns; const InterInstruction* iins = ins.mIns;
if (index)
ins.mMode = ASMIM_ABSOLUTE_Y; ins.mMode = ASMIM_ABSOLUTE_Y;
else if (ins.mLinkerObject || address >= 256)
ins.mMode = ASMIM_ABSOLUTE;
else
ins.mMode = ASMIM_ZERO_PAGE;
ins.mLinkerObject = lobj; ins.mLinkerObject = lobj;
ins.mAddress = address + yval; ins.mAddress = address + yval;
ins.mFlags = (ins.mFlags & ~(NCIF_LOWER | NCIF_UPPER)) | flags; ins.mFlags = (ins.mFlags & ~(NCIF_LOWER | NCIF_UPPER)) | flags;
if (index)
{
if (ins.mLive & LIVE_CPU_REG_Y) if (ins.mLive & LIVE_CPU_REG_Y)
{ {
mIns.Insert(at + 1, NativeCodeInstruction(iins, ASMIT_LDY, ASMIM_IMMEDIATE, yval)); mIns.Insert(at + 1, NativeCodeInstruction(iins, ASMIT_LDY, ASMIM_IMMEDIATE, yval));
@ -29090,6 +29158,7 @@ bool NativeCodeBasicBlock::PatchGlobalAddressSumYPointer(const NativeCodeBasicBl
} }
} }
mIns.Insert(at, NativeCodeInstruction(iins, ASMIT_LDY, ASMIM_ZERO_PAGE, index)); mIns.Insert(at, NativeCodeInstruction(iins, ASMIT_LDY, ASMIM_ZERO_PAGE, index));
}
at++; at++;
changed = true; changed = true;
@ -29110,7 +29179,7 @@ bool NativeCodeBasicBlock::PatchGlobalAddressSumYPointer(const NativeCodeBasicBl
} }
else if (ins.ChangesYReg()) else if (ins.ChangesYReg())
yval = -1; yval = -1;
else if (at + 6 < mIns.Size() && else if (index && at + 6 < mIns.Size() &&
mIns[at + 0].mType == ASMIT_CLC && mIns[at + 0].mType == ASMIT_CLC &&
mIns[at + 1].mType == ASMIT_LDA && mIns[at + 1].mMode == ASMIM_ZERO_PAGE && mIns[at + 1].mAddress == reg + 0 && mIns[at + 1].mType == ASMIT_LDA && mIns[at + 1].mMode == ASMIM_ZERO_PAGE && mIns[at + 1].mAddress == reg + 0 &&
mIns[at + 2].mType == ASMIT_ADC && mIns[at + 2].mMode == ASMIM_IMMEDIATE && mIns[at + 2].mType == ASMIT_ADC && mIns[at + 2].mMode == ASMIM_IMMEDIATE &&
@ -49023,6 +49092,23 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate(int pass)
if (i + 5 < mIns.Size() && PeepHoleOptimizerIterate6(i, pass)) progress = true; if (i + 5 < mIns.Size() && PeepHoleOptimizerIterate6(i, pass)) progress = true;
CheckLive(); CheckLive();
#if 1
if (i + 3 < mIns.Size() && pass == 0 &&
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE &&
mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_IMMEDIATE &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 &&
!(mIns[i + 3].mLive & LIVE_CPU_REG_A))
{
mProc->ResetPatched();
if (CheckGlobalAddressSumYPointer(this, mIns[i + 1].mAddress, 0, i + 4, -1))
{
mProc->ResetPatched();
if (PatchGlobalAddressSumYPointer(this, mIns[i + 1].mAddress, 0, i + 4, -1, nullptr, 256 * mIns[i + 2].mAddress + mIns[i + 0].mAddress))
progress = true;
}
}
#endif
if (i + 2 < mIns.Size() && pass == 0 && if (i + 2 < mIns.Size() && pass == 0 &&
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
@ -50857,7 +50943,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mInterProc = proc; mInterProc = proc;
mInterProc->mLinkerObject->mNativeProc = this; mInterProc->mLinkerObject->mNativeProc = this;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "main"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "a");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];
@ -51718,6 +51804,8 @@ void NativeCodeProcedure::Optimize(void)
ResetVisited(); ResetVisited();
mEntryBlock->CheckAsmCode(); mEntryBlock->CheckAsmCode();
#endif #endif
int t = 0; int t = 0;
#if 1 #if 1
do do

View File

@ -32,6 +32,7 @@ struct NativeRegisterData
void Reset(void); void Reset(void);
void ResetMask(void); void ResetMask(void);
void ResetAliasing(void);
bool SameData(const NativeRegisterData& d) const; bool SameData(const NativeRegisterData& d) const;
bool SameData(const NativeCodeInstruction& ins) const; bool SameData(const NativeCodeInstruction& ins) const;
@ -57,6 +58,7 @@ struct NativeRegisterDataSet
void ResetWorkMasks(void); void ResetWorkMasks(void);
void Intersect(const NativeRegisterDataSet& set); void Intersect(const NativeRegisterDataSet& set);
void IntersectMask(const NativeRegisterDataSet& set); void IntersectMask(const NativeRegisterDataSet& set);
void ResetAliasing(void);
}; };
struct ValueNumberingData struct ValueNumberingData
@ -123,6 +125,7 @@ static const uint32 NCIF_JSRFLAGS = 0x00000080;
static const uint32 NICT_INDEXFLIPPED = 0x00000100; static const uint32 NICT_INDEXFLIPPED = 0x00000100;
static const uint32 NICT_ZPFLIPPED = 0x00000200; static const uint32 NICT_ZPFLIPPED = 0x00000200;
static const uint32 NICF_TMPREF = 0x00000400; static const uint32 NICF_TMPREF = 0x00000400;
static const uint32 NCIF_ALIASING = 0x00000800;
static const uint32 NCIF_USE_CPU_REG_A = 0x00001000; static const uint32 NCIF_USE_CPU_REG_A = 0x00001000;
static const uint32 NCIF_USE_CPU_REG_X = 0x00002000; static const uint32 NCIF_USE_CPU_REG_X = 0x00002000;

View File

@ -478,7 +478,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
mdec->mOffset--; mdec->mOffset--;
mdec->mShift = 8 - bitsleft; mdec->mShift = 8 - bitsleft;
bitsleft = bitsleft + 24 - mdec->mBits; bitsleft = bitsleft + 24 - mdec->mBits;
offset+=2; offset+=3;
} }
else else
{ {