Improve labels in disassembler listing, add mlb file for nes

This commit is contained in:
drmortalwombat 2023-03-09 19:29:46 +01:00
parent 2959016496
commit efff725745
8 changed files with 539 additions and 34 deletions

View File

@ -570,9 +570,9 @@ void flush_vram_update(unsigned char *buf)
else else
{ {
if (c < 0x80) if (c < 0x80)
ppu.control = PPU_CTRL_VAR | 0x04;
else if (c != 0xff)
ppu.control = PPU_CTRL_VAR & ~0x04; ppu.control = PPU_CTRL_VAR & ~0x04;
else if (c != 0xff)
ppu.control = PPU_CTRL_VAR | 0x04;
else else
return; return;

View File

@ -821,10 +821,14 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
} }
else if (mCompilerOptions & COPT_TARGET_NES) else if (mCompilerOptions & COPT_TARGET_NES)
{ {
strcpy_s(lblPath, prgPath);
strcat_s(lblPath, "mlb");
strcat_s(prgPath, "nes"); strcat_s(prgPath, "nes");
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", prgPath); printf("Writing <%s>\n", prgPath);
mLinker->WriteNesFile(prgPath); mLinker->WriteNesFile(prgPath);
} }
@ -852,7 +856,11 @@ bool Compiler::WriteOutputFile(const char* targetPath, DiskImage * d64)
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", lblPath); printf("Writing <%s>\n", lblPath);
mLinker->WriteLblFile(lblPath);
if (mCompilerOptions & COPT_TARGET_NES)
mLinker->WriteMlbFile(lblPath);
else
mLinker->WriteLblFile(lblPath);
if (mCompilerOptions & COPT_VERBOSE) if (mCompilerOptions & COPT_VERBOSE)
printf("Writing <%s>\n", intPath); printf("Writing <%s>\n", intPath);

View File

@ -756,7 +756,13 @@ const char* NativeCodeDisassembler::AddrName(int addr, char* buffer, Linker* lin
LinkerObject* obj = linker->FindObjectByAddr(addr); LinkerObject* obj = linker->FindObjectByAddr(addr);
if (obj && obj->mIdent) if (obj && obj->mIdent)
{ {
sprintf_s(buffer, 160, "; (%s + %d)", obj->mIdent->mString, addr - obj->mAddress); int i = 0;
while (i < obj->mRanges.Size() && (addr - obj->mAddress < obj->mRanges[i].mOffset || addr - obj->mAddress - obj->mRanges[i].mOffset >= obj->mRanges[i].mSize))
i++;
if (i < obj->mRanges.Size())
sprintf_s(buffer, 160, "; (%s.%s + %d)", obj->mIdent->mString, obj->mRanges[i].mIdent->mString, addr - obj->mAddress - obj->mRanges[i].mOffset);
else
sprintf_s(buffer, 160, "; (%s + %d)", obj->mIdent->mString, addr - obj->mAddress);
return buffer; return buffer;
} }
} }

View File

@ -238,6 +238,82 @@ void InterCodeGenerator::InitLocalVariable(InterCodeProcedure* proc, Declaration
proc->mLocalVars[index]->mIdent = dec->mIdent; proc->mLocalVars[index]->mIdent = dec->mIdent;
} }
} }
static const Ident* StructIdent(const Ident* base, const Ident* item)
{
if (base)
{
char buffer[200];
strcpy_s(buffer, base->mString);
strcat_s(buffer, ".");
strcat_s(buffer, item->mString);
return Ident::Unique(buffer);
}
else
return item;
}
static void AddGlobalVariableRanges(LinkerObject* lo, Declaration* dec, int offset, const Ident* ident)
{
switch (dec->mType)
{
case DT_TYPE_STRUCT:
{
Declaration* deci = dec->mParams;
while (deci)
{
AddGlobalVariableRanges(lo, deci->mBase, offset + deci->mOffset, StructIdent(ident, deci->mIdent));
deci = deci->mNext;
}
} break;
case DT_TYPE_INTEGER:
case DT_TYPE_FLOAT:
case DT_TYPE_POINTER:
case DT_TYPE_BOOL:
case DT_TYPE_ENUM:
{
LinkerObjectRange range;
range.mOffset = offset;
range.mSize = dec->mStripe;
switch (dec->mSize)
{
case 1:
range.mIdent = ident;
lo->mRanges.Push(range);
break;
case 2:
range.mIdent = StructIdent(ident, Ident::Unique("lo"));
lo->mRanges.Push(range);
range.mOffset += dec->mStripe;
range.mIdent = StructIdent(ident, Ident::Unique("hi"));
lo->mRanges.Push(range);
break;
case 4:
range.mIdent = StructIdent(ident, Ident::Unique("b0"));
lo->mRanges.Push(range);
range.mOffset += dec->mStripe;
range.mIdent = StructIdent(ident, Ident::Unique("b1"));
lo->mRanges.Push(range);
range.mOffset += dec->mStripe;
range.mIdent = StructIdent(ident, Ident::Unique("b2"));
lo->mRanges.Push(range);
range.mOffset += dec->mStripe;
range.mIdent = StructIdent(ident, Ident::Unique("b3"));
lo->mRanges.Push(range);
break;
}
} break;
default:
if (ident)
{
LinkerObjectRange range;
range.mIdent = ident;
range.mOffset = offset;
range.mSize = dec->mSize * dec->mStripe;
lo->mRanges.Push(range);
}
}
}
void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* dec) void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* dec)
{ {
@ -249,6 +325,13 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment); var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment);
var->mIdent = dec->mIdent; var->mIdent = dec->mIdent;
Declaration* decb = dec->mBase;
while (decb && decb->mType == DT_TYPE_ARRAY)
decb = decb->mBase;
if (decb && decb->mStripe != 1)
AddGlobalVariableRanges(var->mLinkerObject, decb, 0, nullptr);
Declaration* type = dec->mBase; Declaration* type = dec->mBase;
while (type->mType == DT_TYPE_ARRAY) while (type->mType == DT_TYPE_ARRAY)
type = type->mBase; type = type->mBase;

View File

@ -944,6 +944,49 @@ bool Linker::WriteMapFile(const char* filename)
return false; return false;
} }
bool Linker::WriteMlbFile(const char* filename)
{
FILE* file;
fopen_s(&file, filename, "wb");
if (file)
{
fprintf(file, "R:%02x-%02x:__ACCU\n", BC_REG_ACCU, BC_REG_ACCU + 3);
fprintf(file, "R:%02x-%02x:__ADDR\n", BC_REG_ADDR, BC_REG_ADDR + 1);
fprintf(file, "R:%02x-%02x:__IP\n", BC_REG_IP, BC_REG_IP + 1);
fprintf(file, "R:%02x-%02x:__SP\n", BC_REG_STACK, BC_REG_STACK + 1);
fprintf(file, "R:%02x-%02x:__FP\n", BC_REG_LOCALS, BC_REG_LOCALS + 1);
fprintf(file, "R:%02x-%02x:__P\n", BC_REG_FPARAMS, BC_REG_FPARAMS_END - 1);
fprintf(file, "R:%02x-%02x:__T\n", BC_REG_TMP, 0x7f);
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* obj = mObjects[i];
if ((obj->mFlags & LOBJF_REFERENCED) && obj->mIdent && obj->mSize > 0)
{
if (obj->mSection->mType == LST_BSS)
fprintf(file, "R:%04x-%04x:%s\n", obj->mAddress, obj->mAddress + obj->mSize - 1, obj->mIdent->mString);
else if (obj->mType == LOT_DATA)
{
if (!obj->mRegion->mCartridgeBanks)
fprintf(file, "P:%04x-%04x:%s\n", obj->mAddress - 0x8000, obj->mAddress - 0x8000 + obj->mSize - 1, obj->mIdent->mString);
}
else if (obj->mType == LOT_NATIVE_CODE)
{
if (!obj->mRegion->mCartridgeBanks)
fprintf(file, "P:%04x:%s\n", obj->mAddress - 0x8000, obj->mIdent->mString);
}
}
}
fclose(file);
return true;
}
else
return false;
}
bool Linker::WriteLblFile(const char* filename) bool Linker::WriteLblFile(const char* filename)
{ {
FILE* file; FILE* file;

View File

@ -151,24 +151,33 @@ static const uint32 LOBJF_RET_REG_A = 0x00010000;
static const uint32 LOBJF_RET_REG_X = 0x00020000; static const uint32 LOBJF_RET_REG_X = 0x00020000;
class LinkerObjectRange
{
public:
const Ident * mIdent;
int mOffset, mSize;
};
class LinkerObject class LinkerObject
{ {
public: public:
Location mLocation; Location mLocation;
const Ident * mIdent; const Ident * mIdent;
LinkerObjectType mType; LinkerObjectType mType;
int mID; int mID;
int mAddress, mRefAddress; int mAddress, mRefAddress;
int mSize, mAlignment; int mSize, mAlignment;
LinkerSection * mSection; LinkerSection * mSection;
LinkerRegion * mRegion; LinkerRegion * mRegion;
uint8 * mData; uint8 * mData;
InterCodeProcedure * mProc; InterCodeProcedure * mProc;
uint32 mFlags; uint32 mFlags;
uint8 mTemporaries[16], mTempSizes[16]; uint8 mTemporaries[16], mTempSizes[16];
int mNumTemporaries; int mNumTemporaries;
ZeroPageSet mZeroPageSet; ZeroPageSet mZeroPageSet;
LinkerSection * mStackSection; LinkerSection * mStackSection;
ExpandingArray<LinkerObjectRange> mRanges;
LinkerObject(void); LinkerObject(void);
~LinkerObject(void); ~LinkerObject(void);
@ -230,6 +239,7 @@ public:
bool WriteCrtFile(const char* filename); bool WriteCrtFile(const char* filename);
bool WriteBinFile(const char* filename); bool WriteBinFile(const char* filename);
bool WriteNesFile(const char* filename); bool WriteNesFile(const char* filename);
bool WriteMlbFile(const char* filename);
uint64 mCompilerOptions; uint64 mCompilerOptions;

View File

@ -3235,26 +3235,44 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
} }
break; break;
case ASMIT_TAX: case ASMIT_TAX:
data.ResetX(); if (data.mRegs[CPU_REG_X].SameData(data.mRegs[CPU_REG_A]) && !(mLive & LIVE_CPU_REG_Z))
data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A];
if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE)
{ {
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; mType = ASMIT_NOP;
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue; mMode = ASMIM_IMPLIED;
changed = true;
} }
else else
data.mRegs[CPU_REG_Z].Reset(); {
data.ResetX();
data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A];
if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE)
{
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue;
}
else
data.mRegs[CPU_REG_Z].Reset();
}
break; break;
case ASMIT_TAY: case ASMIT_TAY:
data.ResetY(); if (data.mRegs[CPU_REG_Y].SameData(data.mRegs[CPU_REG_A]) && !(mLive & LIVE_CPU_REG_Z))
data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A];
if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE)
{ {
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; mType = ASMIT_NOP;
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue; mMode = ASMIM_IMPLIED;
changed = true;
} }
else else
data.mRegs[CPU_REG_Z].Reset(); {
data.ResetY();
data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A];
if (data.mRegs[CPU_REG_A].mMode == NRDM_IMMEDIATE)
{
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue;
}
else
data.mRegs[CPU_REG_Z].Reset();
}
break; break;
} }
@ -13139,6 +13157,202 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full)
return changed; return changed;
} }
bool NativeCodeBasicBlock::CanCombineSameYtoX(int start, int end)
{
for (int i = start; i < end; i++)
{
NativeCodeInstruction& ins(mIns[i]);
if (ins.mMode == ASMIM_INDIRECT_Y)
return false;
if (ins.mMode == ASMIM_ABSOLUTE_Y && !HasAsmInstructionMode(ins.mType, ASMIM_ABSOLUTE_X))
return false;
}
return true;
}
bool NativeCodeBasicBlock::CanCombineSameXtoY(int start, int end)
{
for (int i = start; i < end; i++)
{
NativeCodeInstruction& ins(mIns[i]);
if (ins.mMode == ASMIM_INDIRECT_X)
return false;
if (ins.mMode == ASMIM_ABSOLUTE_X && !HasAsmInstructionMode(ins.mType, ASMIM_ABSOLUTE_Y))
return false;
}
return true;
}
bool NativeCodeBasicBlock::CombineSameXtoY(int xpos, int ypos, int end)
{
if (xpos < ypos)
{
if (CanCombineSameXtoY(xpos, ypos) &&
CanCombineSameXtoY(ypos, end))
{
ReplaceXRegWithYReg(xpos, ypos);
ReplaceXRegWithYReg(ypos, end);
return true;
}
}
else
{
if (CanCombineSameXtoY(xpos, end))
{
ReplaceXRegWithYReg(xpos, end);
#if 0
if (!(mIns[xpos].mLive & LIVE_CPU_REG_Z))
{
mIns[xpos].mType = ASMIT_NOP;
mIns[xpos].mMode = ASMIM_IMPLIED;
}
#endif
return true;
}
}
return false;
}
bool NativeCodeBasicBlock::CombineSameYtoX(int xpos, int ypos, int end)
{
if (ypos < xpos)
{
if (CanCombineSameYtoX(ypos, xpos) &&
CanCombineSameYtoX(xpos + 1, end))
{
ReplaceYRegWithXReg(ypos, xpos);
ReplaceYRegWithXReg(xpos + 1, end);
return true;
}
}
else
{
if (CanCombineSameYtoX(ypos, end))
{
ReplaceYRegWithXReg(ypos, end);
#if 0
if (!(mIns[ypos].mLive & LIVE_CPU_REG_Z))
{
mIns[ypos].mType = ASMIT_NOP;
mIns[ypos].mMode = ASMIM_IMPLIED;
}
#endif
return true;
}
}
return false;
}
bool NativeCodeBasicBlock::CombineSameXY(void)
{
bool changed = false;
if (!mVisited)
{
mVisited = true;
int xreg = -1, yreg = -1;
int xpos, ypos;
bool samexy = false;
for (int i = 0; i < mIns.Size(); i++)
{
NativeCodeInstruction& ins(mIns[i]);
if (ins.ChangesXReg())
{
if (samexy && CombineSameXtoY(xpos, ypos, i))
changed = true;
xreg = -1;
samexy = false;
}
if (ins.ChangesYReg())
{
if (samexy && CombineSameYtoX(ypos, xpos, i))
changed = true;
yreg = -1;
samexy = false;
}
if (ins.mType == ASMIT_TAX)
{
xreg = CPU_REG_A;
xpos = i;
samexy = yreg == xreg;
}
else if (ins.mType == ASMIT_TAY)
{
yreg = CPU_REG_A;
ypos = i;
samexy = xreg == yreg;
}
else if (ins.mType == ASMIT_LDX)
{
if (ins.mMode == ASMIM_ZERO_PAGE)
{
xreg = ins.mAddress;
xpos = i;
samexy = yreg == xreg;
}
else
xreg = -1;
}
else if (ins.mType == ASMIT_LDY)
{
if (ins.mMode == ASMIM_ZERO_PAGE)
{
yreg = ins.mAddress;
ypos = i;
samexy = xreg == yreg;
}
else
yreg = -1;
}
else if (ins.ChangesAccu())
{
if (xreg == CPU_REG_A)
xreg = -1;
if (yreg == CPU_REG_A)
yreg = -1;
}
else if (ins.mMode == ASMIM_ZERO_PAGE && ins.ChangesAddress())
{
if (xreg == ins.mAddress)
xreg = -1;
if (yreg == ins.mAddress)
yreg = -1;
}
}
if (samexy)
{
if (!mExitRequiredRegs[CPU_REG_X] && CombineSameXtoY(xpos, ypos, mIns.Size()))
changed = true;
else if (!mExitRequiredRegs[CPU_REG_Y] && CombineSameYtoX(xpos, ypos, mIns.Size()))
changed = true;
}
if (mTrueJump && mTrueJump->CombineSameXY())
changed = true;
if (mFalseJump && mFalseJump->CombineSameXY())
changed = true;
}
return changed;
}
bool NativeCodeBasicBlock::RegisterValueForwarding(void) bool NativeCodeBasicBlock::RegisterValueForwarding(void)
{ {
bool changed = false; bool changed = false;
@ -14920,6 +15134,89 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc)
break; break;
} }
if (mIns[i + 0].mType == ASMIT_TXA &&
mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 3].mLive & LIVE_CPU_REG_X) &&
mIns[i + 4].mType == ASMIT_LDA &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
mIns[i + 6].mType == ASMIT_STA && mIns[i + 4].SameEffectiveAddress(mIns[i + 6]) &&
HasAsmInstructionMode(ASMIT_INC, mIns[i + 6].mMode) &&
!(mIns[i + 6].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
{
changed = true;
NativeCodeBasicBlock* iblock = proc->AllocateBlock();
NativeCodeBasicBlock* fblock = proc->AllocateBlock();
fblock->mTrueJump = mTrueJump;
fblock->mFalseJump = mFalseJump;
fblock->mBranch = mBranch;
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 1].mType = ASMIT_NOP;
mIns[i + 2].mType = ASMIT_INX; mIns[i + 2].mLive |= LIVE_CPU_REG_Z | LIVE_CPU_REG_X;
mIns[i + 3].mType = ASMIT_STX; mIns[i + 3].mLive |= LIVE_CPU_REG_Z;
fblock->mIns.Push(mIns[i + 4]);
for (int j = i + 7; j < mIns.Size(); j++)
fblock->mIns.Push(mIns[j]);
iblock->mIns.Push(mIns[i + 6]);
mIns.SetSize(i + 4);
iblock->mIns[0].mType = ASMIT_INC;
iblock->mTrueJump = fblock;
iblock->mBranch = ASMIT_JMP;
mTrueJump = fblock;
mFalseJump = iblock;
mBranch = ASMIT_BNE;
break;
}
if (mIns[i + 0].mType == ASMIT_TYA &&
mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 3].mLive & LIVE_CPU_REG_Y) &&
mIns[i + 4].mType == ASMIT_TXA &&
mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 &&
mIns[i + 6].mType == ASMIT_TAX &&
!(mIns[i + 6].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_Z)))
{
changed = true;
NativeCodeBasicBlock* iblock = proc->AllocateBlock();
NativeCodeBasicBlock* fblock = proc->AllocateBlock();
fblock->mTrueJump = mTrueJump;
fblock->mFalseJump = mFalseJump;
fblock->mBranch = mBranch;
mIns[i + 0].mType = ASMIT_NOP;
mIns[i + 1].mType = ASMIT_NOP;
mIns[i + 2].mType = ASMIT_INY; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_Z | LIVE_CPU_REG_Y;
mIns[i + 3].mType = ASMIT_STY; mIns[i + 3].mLive |= LIVE_CPU_REG_Z;
fblock->mIns.Push(NativeCodeInstruction(ASMIT_TXA));
for (int j = i + 7; j < mIns.Size(); j++)
fblock->mIns.Push(mIns[j]);
iblock->mIns.Push(NativeCodeInstruction(ASMIT_INX));
mIns.SetSize(i + 4);
iblock->mTrueJump = fblock;
iblock->mBranch = ASMIT_JMP;
mTrueJump = fblock;
mFalseJump = iblock;
mBranch = ASMIT_BNE;
break;
}
if (mIns[i + 0].mType == ASMIT_TYA && if (mIns[i + 0].mType == ASMIT_TYA &&
mIns[i + 1].mType == ASMIT_CLC && mIns[i + 1].mType == ASMIT_CLC &&
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 &&
@ -25686,6 +25983,50 @@ bool NativeCodeBasicBlock::OptimizeLoopCarryOver(void)
changed = true; changed = true;
} }
} }
int sz = mIns.Size();
if (sz > 0)
{
hblock = nullptr;
if (mTrueJump->mLoopHead)
hblock = mTrueJump;
else if (mFalseJump->mLoopHead)
hblock = mFalseJump;
if (hblock && hblock->mIns.Size() > 0 && hblock->mNumEntries == 2)
{
NativeCodeBasicBlock* pblock;
if (hblock->mEntryBlocks[0] == this)
pblock = hblock->mEntryBlocks[1];
else
pblock = hblock->mEntryBlocks[0];
if (!pblock->mFalseJump)
{
if (hblock->mIns[0].mType == ASMIT_TAX && mIns[sz - 1].mType == ASMIT_TXA && !(hblock->mIns[0].mLive & LIVE_CPU_REG_Z))
{
pblock->mIns.Push(NativeCodeInstruction(ASMIT_TAX));
hblock->mIns.Remove(0);
pblock->mExitRequiredRegs += CPU_REG_X;
hblock->mEntryRequiredRegs += CPU_REG_X;
mExitRequiredRegs += CPU_REG_X;
changed = true;
}
else if (hblock->mIns[0].mType == ASMIT_TAY && mIns[sz - 1].mType == ASMIT_TYA && !(hblock->mIns[0].mLive & LIVE_CPU_REG_Z))
{
pblock->mIns.Push(NativeCodeInstruction(ASMIT_TAY));
hblock->mIns.Remove(0);
pblock->mExitRequiredRegs += CPU_REG_Y;
hblock->mEntryRequiredRegs += CPU_REG_Y;
mExitRequiredRegs += CPU_REG_Y;
changed = true;
}
}
}
}
} }
if (mTrueJump && mTrueJump->OptimizeLoopCarryOver()) if (mTrueJump && mTrueJump->OptimizeLoopCarryOver())
@ -32212,6 +32553,14 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
progress = true; progress = true;
} }
else if (
mIns[i + 0].mType == ASMIT_SEC &&
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0xff &&
mIns[i + 2].mType == ASMIT_SBC)
{
mIns[i + 2].mType = ASMIT_EOR;
progress = true;
}
else if ( else if (
mIns[i + 0].mType == ASMIT_EOR && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0x80 && mIns[i + 0].mType == ASMIT_EOR && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0x80 &&
mIns[i + 1].mType == ASMIT_SEC && mIns[i + 1].mType == ASMIT_SEC &&
@ -37389,13 +37738,14 @@ void NativeCodeProcedure::Optimize(void)
ResetVisited(); ResetVisited();
if (mEntryBlock->MoveAccuTrainsDown()) if (mEntryBlock->MoveAccuTrainsDown())
changed = true; changed = true;
ResetVisited();
if (mEntryBlock->CombineSameXY())
changed = true;
} }
#endif #endif
#if 1 #if 1
if (step == 6) if (step == 6)
{ {

View File

@ -377,6 +377,11 @@ public:
bool ForwardZpXIndex(bool full); bool ForwardZpXIndex(bool full);
bool RegisterValueForwarding(void); bool RegisterValueForwarding(void);
bool CanCombineSameXtoY(int start, int end);
bool CanCombineSameYtoX(int start, int end);
bool CombineSameXY(void);
bool CombineSameXtoY(int xpos, int ypos, int end);
bool CombineSameYtoX(int xpos, int ypos, int end);
bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains); bool FindImmediateStore(int at, int reg, const NativeCodeInstruction*& ains);