Fix inline assembler optimzier for JSR returning result in X and Y

This commit is contained in:
drmortalwombat 2025-05-10 13:13:27 +02:00
parent 42299c9406
commit 4837ceb73f
3 changed files with 50 additions and 9 deletions

View File

@ -163,6 +163,7 @@ static const uint32 LOBJF_ARG_REG_Y = 0x00004000;
static const uint32 LOBJF_RET_REG_A = 0x00010000;
static const uint32 LOBJF_RET_REG_X = 0x00020000;
static const uint32 LOBJF_RET_REG_Y = 0x00020000;
static const uint32 LOBJF_LOCAL_VAR = 0x00100000;
static const uint32 LOBJF_LOCAL_USED = 0x00200000;

View File

@ -1248,7 +1248,7 @@ bool NativeCodeInstruction::CanSwapXYReg(void)
return mType == ASMIT_LDY || HasAsmInstructionMode(mType, ASMIM_ABSOLUTE_Y);
else if (mMode == ASMIM_ABSOLUTE_Y)
return mType == ASMIT_LDX || HasAsmInstructionMode(mType, ASMIM_ABSOLUTE_X);
else if (mType == ASMIT_JSR && (mFlags & (NCIF_USE_CPU_REG_X | NCIF_USE_CPU_REG_Y)))
else if (mType == ASMIT_JSR && (mFlags & (NCIF_USE_CPU_REG_X | NCIF_USE_CPU_REG_Y | NCIF_PROVIDE_CPU_REG_X | NCIF_PROVIDE_CPU_REG_Y)))
return false;
else
return true;
@ -14470,7 +14470,7 @@ void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, NativeCodePro
ExpandingArray<NativeCodeInstruction> tains;
uint32 uflags = 0;
bool simple = true;
bool simple = true, jsrs = false;
int i = 0;
while (i < ins->mSrc[0].mLinkerObject->mSize)
{
@ -14484,6 +14484,7 @@ void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, NativeCodePro
if (dins.mType == ASMIT_JSR)
{
dins.mFlags |= uflags | NCIF_JSRFLAGS;
jsrs = true;
}
if (dins.mType == ASMIT_BRK || dins.mMode == ASMIM_INDIRECT_X || dins.mMode == ASMIM_INDIRECT ||
@ -14515,6 +14516,39 @@ void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, NativeCodePro
if (simple)
{
if (jsrs && (uflags & (NCIF_USE_CPU_REG_A | NCIF_USE_CPU_REG_X | NCIF_USE_CPU_REG_Y)))
{
int live = 0;
for (int i = tains.Size() - 1; i >= 0; i--)
{
if (tains[i].mType == ASMIT_JSR)
{
if (live & LIVE_CPU_REG_A)
tains[i].mFlags |= NCIF_PROVIDE_CPU_REG_A;
if (live & LIVE_CPU_REG_X)
tains[i].mFlags |= NCIF_PROVIDE_CPU_REG_X;
if (live & LIVE_CPU_REG_Y)
tains[i].mFlags |= NCIF_PROVIDE_CPU_REG_Y;
live = 0;
}
else
{
if (tains[i].ChangesAccu())
live &= ~LIVE_CPU_REG_A;
if (tains[i].ChangesXReg())
live &= ~LIVE_CPU_REG_X;
if (tains[i].ChangesYReg())
live &= ~LIVE_CPU_REG_Y;
if (tains[i].RequiresAccu())
live |= LIVE_CPU_REG_A;
if (tains[i].RequiresXReg())
live |= LIVE_CPU_REG_X;
if (tains[i].RequiresYReg())
live |= LIVE_CPU_REG_Y;
}
}
}
for (int i = 0; i + 1 < tains.Size(); i++)
mIns.Push(tains[i]);
}
@ -53751,7 +53785,8 @@ void NativeCodeBasicBlock::CheckLive(void)
if (mIns[j].mType == ASMIT_JSR)
{
assert(!(live & (LIVE_CPU_REG_X | LIVE_CPU_REG_Y)));
assert((mIns[j].mFlags & NCIF_PROVIDE_CPU_REG_X) || !(live & LIVE_CPU_REG_X));
assert((mIns[j].mFlags & NCIF_PROVIDE_CPU_REG_Y) || !(live & LIVE_CPU_REG_Y));
if (!(mIns[j].mFlags & NCIF_JSRFLAGS))
assert(!(live & (LIVE_CPU_REG_C | LIVE_CPU_REG_Z)));
}
@ -54605,7 +54640,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
mInterProc->mLinkerObject->mNativeProc = this;
CheckFunc = !strcmp(mIdent->mString, "chests");
CheckFunc = !strcmp(mIdent->mString, "main");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];

View File

@ -135,12 +135,17 @@ static const uint32 NCIF_USE_CPU_REG_X = 0x00002000;
static const uint32 NCIF_USE_CPU_REG_Y = 0x00004000;
static const uint32 NCIF_USE_CPU_REG_C = 0x00008000;
// use a 32bit zero page register indexed by X for JSR
static const uint32 NCIF_USE_ZP_32_X = 0x00010000;
static const uint32 NICF_USE_ZP_ADDR = 0x00020000;
static const uint32 NICF_USE_WORKREGS = 0x00040000;
static const uint32 NCIF_PROVIDE_CPU_REG_A = 0x00010000;
static const uint32 NCIF_PROVIDE_CPU_REG_X = 0x00020000;
static const uint32 NCIF_PROVIDE_CPU_REG_Y = 0x00040000;
static const uint32 NCIF_PROVIDE_CPU_REG_C = 0x00080000;
static const uint32 NCIF_BREAKPOINT = 0x00080000;
// use a 32bit zero page register indexed by X for JSR
static const uint32 NCIF_USE_ZP_32_X = 0x00100000;
static const uint32 NICF_USE_ZP_ADDR = 0x00200000;
static const uint32 NICF_USE_WORKREGS = 0x00400000;
static const uint32 NCIF_BREAKPOINT = 0x00800000;
class NativeCodeInstruction
{