diff --git a/README.md b/README.md index 34f63ed..ca7221b 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,7 @@ The C64 does not use ASCII it uses a derivative called PETSCII. There are two f The translation mode is selected in conio with the variable "giocharmap" and the function "iocharmap" which will also switch the font. iocharmap(IOCHM_PETSCII_2); - printf("Hello World\"); + printf("Hello World\n"); Will switch to the lowercase PETSCII font and translate the strings while printing. diff --git a/include/c64/cia.h b/include/c64/cia.h new file mode 100644 index 0000000..0578fd3 --- /dev/null +++ b/include/c64/cia.h @@ -0,0 +1,23 @@ +#ifndef C64_CIA +#define C64_CIA + +#include "types.h" + +struct CIA +{ + byte pra, prb; + byte ddra, ddrb; + word ta, tb; + byte todt, tods, todm, todh; + byte sdr; + byte icr; + byte cra, crb; +}; + +#define cia1 (*((CIA *)0xdc00)) +#define cia2 (*((CIA *)0xdd00)) + +#endif + + + diff --git a/include/c64/vic.c b/include/c64/vic.c new file mode 100644 index 0000000..6921f25 --- /dev/null +++ b/include/c64/vic.c @@ -0,0 +1,7 @@ +#include "vic.h" +#include "cia.h" + +void vic_setbank(char bank) +{ + cia2.pra = (cia2.pra & 0xfc) | (bank ^ 0x03); +} diff --git a/include/c64/vic.h b/include/c64/vic.h index cb14683..a245d32 100644 --- a/include/c64/vic.h +++ b/include/c64/vic.h @@ -9,9 +9,9 @@ #define VIC_CTRL1_ECM 0x40 #define VIC_CTRL1_RST8 0x80 -#define VIC_CTRL2_CSEL 0x10 -#define VIC_CTRL2_MCM 0x20 -#define VIC_CTRL2_RES 0x40 +#define VIC_CTRL2_CSEL 0x08 +#define VIC_CTRL2_MCM 0x10 +#define VIC_CTRL2_RES 0x20 #define VIC_INTR_RST 0x01 #define VIC_INTR_MBC 0x02 @@ -45,7 +45,7 @@ struct VIC struct XY { byte x, y; - } spritexy[8]; + } spr_pos[8]; byte spr_msbx; byte ctrl1; @@ -73,6 +73,10 @@ struct VIC }; +void vic_setbank(char bank); + #define vic (*((VIC *)0xd000)) +#pragma compile("vic.c") + #endif diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index a14f1c1..6d0a1d5 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -86,7 +86,7 @@ void ValueSet::FlushCallAliases(void) } } -static int64 ConstantFolding(InterOperator oper, int64 val1, int64 val2) +static int64 ConstantFolding(InterOperator oper, int64 val1, int64 val2 = 0) { switch (oper) { @@ -3357,6 +3357,27 @@ static bool CanBypassLoad(const InterInstruction * lins, const InterInstruction return true; } +static bool CanBypass(const InterInstruction* lins, const InterInstruction* bins) +{ + if (lins->mDst.mTemp >= 0) + { + if (lins->mDst.mTemp == bins->mDst.mTemp) + return false; + + for (int i = 0; i < bins->mNumOperands; i++) + if (lins->mDst.mTemp == bins->mSrc[i].mTemp) + return false; + } + if (bins->mDst.mTemp >= 0) + { + for (int i = 0; i < lins->mNumOperands; i++) + if (bins->mDst.mTemp == lins->mSrc[i].mTemp) + return false; + } + + return true; +} + static bool CanBypassStore(const InterInstruction * sins, const InterInstruction * bins) { if (bins->mCode == IC_COPY || bins->mCode == IC_PUSH_FRAME) @@ -3606,6 +3627,10 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa } } +static bool IsCommutative(InterOperator op) +{ + return op == IA_ADD || op == IA_MUL || op == IA_AND || op == IA_OR || op == IA_XOR; +} void InterCodeBasicBlock::PeepholeOptimization(void) { int i; @@ -3629,7 +3654,7 @@ void InterCodeBasicBlock::PeepholeOptimization(void) // shorten lifespan int limit = mInstructions.Size() - 1; - if (limit >= 2 && mInstructions[limit]->mCode == IC_BRANCH) + if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH) limit -= 2; int i = limit; @@ -3649,6 +3674,18 @@ void InterCodeBasicBlock::PeepholeOptimization(void) if (i != j) mInstructions[j] = ins; } + else if (mInstructions[i]->mCode == IC_BINARY_OPERATOR || mInstructions[i]->mCode == IC_UNARY_OPERATOR || mInstructions[i]->mCode == IC_CONVERSION_OPERATOR || mInstructions[i]->mCode == IC_CONSTANT) + { + InterInstruction* ins(mInstructions[i]); + int j = i; + while (j < limit && CanBypass(ins, mInstructions[j + 1])) + { + mInstructions[j] = mInstructions[j + 1]; + j++; + } + if (i != j) + mInstructions[j] = ins; + } i--; } @@ -3696,10 +3733,16 @@ void InterCodeBasicBlock::PeepholeOptimization(void) mInstructions[i + 1]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && (mInstructions[i + 2]->mCode == IC_RELATIONAL_OPERATOR || mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR) && mInstructions[i + 2]->mSrc[0].mTemp == mInstructions[i]->mDst.mTemp && mInstructions[i + 2]->mSrc[0].mFinal) { + int t = mInstructions[i + 0]->mDst.mTemp; mInstructions[i + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp; mInstructions[i + 1]->mCode = IC_NONE; mInstructions[i + 2]->mSrc[0].mTemp = mInstructions[i + 1]->mDst.mTemp; mInstructions[i + 2]->mSrc[0].mFinal = false; + if (mInstructions[i + 2]->mSrc[1].mTemp == t) + { + mInstructions[i + 2]->mSrc[1].mTemp = mInstructions[i + 1]->mDst.mTemp; + mInstructions[i + 2]->mSrc[1].mFinal = false; + } changed = true; } else if (mInstructions[i + 0]->mDst.mTemp >= 0 && @@ -3745,6 +3788,16 @@ void InterCodeBasicBlock::PeepholeOptimization(void) mInstructions[i + 1]->mSrc[0].mTemp = mInstructions[i + 0]->mDst.mTemp; changed = true; } + else if ( + mInstructions[i + 0]->mDst.mTemp >= 0 && + mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && IsCommutative(mInstructions[i + 1]->mOperator) && mInstructions[i + 0]->mDst.mTemp == mInstructions[i + 1]->mSrc[0].mTemp && mInstructions[i + 0]->mDst.mTemp != mInstructions[i + 1]->mSrc[1].mTemp) + { + InterOperand io = mInstructions[i + 1]->mSrc[1]; + mInstructions[i + 1]->mSrc[1] = mInstructions[i + 1]->mSrc[0]; + mInstructions[i + 1]->mSrc[0] = io; + changed = true; + } + // Postincrement artifact if (mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && @@ -4390,11 +4443,11 @@ void InterCodeProcedure::Close(void) ResetVisited(); mEntryBlock->PeepholeOptimization(); + DisassembleDebug("Peephole optimized"); + TempForwarding(); RemoveUnusedInstructions(); - DisassembleDebug("Peephole optimized"); - ResetVisited(); mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 7176fbb..f7713a1 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -523,6 +523,15 @@ bool NativeCodeInstruction::ChangesZeroPage(int address) const return false; } +bool NativeCodeInstruction::UsesZeroPage(int address) const +{ + if (mMode == ASMIM_ZERO_PAGE && mAddress == address) + return true; + else + return false; +} + + bool NativeCodeInstruction::ChangesGlobalMemory(void) const { if (mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_ABSOLUTE || mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_ABSOLUTE_Y) @@ -1475,12 +1484,16 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) { mType = ASMIT_LDA; data.mRegs[CPU_REG_A].Reset(); + data.mRegs[CPU_REG_Z].Reset(); } else { mType = ASMIT_LDA; mMode = ASMIM_IMMEDIATE; mAddress = 0; + + data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE; + data.mRegs[CPU_REG_Z].mValue = 0; } changed = true; } @@ -2540,36 +2553,46 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr { if (ins->mSrc[1].mMemory == IM_INDIRECT) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst)); + int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + int index = ins->mSrc[1].mIntConst; + + CheckFrameIndex(reg, index, 4); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 16) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); } } else { if (ins->mSrc[1].mMemory == IM_INDIRECT) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst)); + int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + int index = ins->mSrc[1].mIntConst; + + CheckFrameIndex(reg, index, 4); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); } } } @@ -2691,24 +2714,34 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr { if (ins->mSrc[1].mMemory == IM_INDIRECT) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst)); + int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + int index = ins->mSrc[1].mIntConst; + + CheckFrameIndex(reg, index, 2); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); } } else { if (ins->mSrc[1].mMemory == IM_INDIRECT) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst)); + int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + int index = ins->mSrc[1].mIntConst; + + CheckFrameIndex(reg, index, 2); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); } } } @@ -3074,28 +3107,33 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr { if (ins->mSrc[1].mMemory == IM_INDIRECT) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst)); + int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + int index = ins->mSrc[1].mIntConst; + + CheckFrameIndex(reg, index, InterTypeSize[ins->mSrc[0].mType]); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); if (InterTypeSize[ins->mSrc[0].mType] == 2) { mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); } else if (InterTypeSize[ins->mSrc[0].mType] == 4) { mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 16) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); } } } @@ -3103,28 +3141,33 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr { if (ins->mSrc[1].mMemory == IM_INDIRECT) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst)); + int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + int index = ins->mSrc[1].mIntConst; + + CheckFrameIndex(reg, index, InterTypeSize[ins->mSrc[0].mType]); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); if (InterTypeSize[ins->mSrc[0].mType] == 2) { mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); } else if (InterTypeSize[ins->mSrc[0].mType] == 4) { mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); } } } @@ -3195,8 +3238,13 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI { if (rins->mSrc[0].mMemory == IM_INDIRECT) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins->mSrc[0].mIntConst)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins->mSrc[0].mTemp])); + int areg = BC_REG_TMP + proc->mTempOffset[rins->mSrc[0].mTemp]; + int index = rins->mSrc[0].mIntConst; + + CheckFrameIndex(areg, index, 1); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); } } @@ -3240,8 +3288,13 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI { if (wins->mSrc[1].mMemory == IM_INDIRECT) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, wins->mSrc[1].mIntConst)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp])); + int areg = BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp]; + int index = wins->mSrc[1].mIntConst; + + CheckFrameIndex(areg, index, 1); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, areg)); } } } @@ -3360,17 +3413,23 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI { if (ins->mSrc[0].mMemory == IM_INDIRECT) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + int index = ins->mSrc[0].mIntConst; + + CheckFrameIndex(areg, index, 4); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); } } @@ -3459,9 +3518,14 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI { if (ins->mSrc[0].mMemory == IM_INDIRECT) { - int src = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src)); + int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + int index = ins->mSrc[0].mIntConst; + + CheckFrameIndex(areg, index, 2); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); if (ainsl) { if (ainsl->mType == ASMIT_ADC) @@ -3470,15 +3534,15 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); mIns.Push(*ainsl); } - if (reg == src) + if (reg == areg) mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED)); else mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); if (ainsh) mIns.Push(*ainsh); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); - if (reg == src) + if (reg == areg) mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, reg)); } } @@ -3676,10 +3740,15 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI { if (ins->mSrc[0].mMemory == IM_INDIRECT) { + int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + int index = ins->mSrc[0].mIntConst; + + CheckFrameIndex(areg, index, InterTypeSize[ins->mDst.mType]); + if (InterTypeSize[ins->mDst.mType] == 1) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); if (ainsl) { if (ainsl->mType == ASMIT_ADC) @@ -3698,10 +3767,8 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI } else if (InterTypeSize[ins->mDst.mType] == 2) { - int src = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; - - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); if (ainsl) { if (ainsl->mType == ASMIT_ADC) @@ -3713,16 +3780,16 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI if (InterTypeSize[ins->mDst.mType] > 1) { - if (reg == src) + if (reg == areg) mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED)); else mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); if (ainsh) mIns.Push(*ainsh); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); - if (reg == src) + if (reg == areg) mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, reg)); } else @@ -3730,20 +3797,18 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI } else if (InterTypeSize[ins->mDst.mType] == 4) { - int src = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; - - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); } } @@ -3835,6 +3900,20 @@ void NativeCodeBasicBlock::ShiftRegisterLeft(InterCodeProcedure* proc, int reg, mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_ZERO_PAGE, reg + 0)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, reg + 1)); } + else if (shift >= 5) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_ZERO_PAGE, reg)); + mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, reg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LSR, ASMIM_IMPLIED)); + for (int i = shift; i < 8; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_ZERO_PAGE, reg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); + } + mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, (0xff << shift) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); + } else { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 1)); @@ -6803,6 +6882,29 @@ bool NativeCodeBasicBlock::MoveIndirectLoadStoreUp(int at) return false; } +bool NativeCodeBasicBlock::MoveAbsoluteLoadStoreUp(int at) +{ + int j = at - 1; + while (j > 0) + { + if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress) + { + mIns.Insert(j + 1, mIns[at + 1]); + mIns[at + 2].mType = ASMIT_NOP; + mIns[at + 2].mMode = ASMIM_IMPLIED; + return true; + } + if (mIns[j].ChangesZeroPage(mIns[at].mAddress)) + return false; + if (mIns[j].ChangesGlobalMemory()) + return false; + + j--; + } + + return false; +} + bool NativeCodeBasicBlock::MoveLoadStoreUp(int at) { int j = at; @@ -6874,6 +6976,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data) changed = true; } +#if 1 if (mFalseJump) { switch (mBranch) @@ -6940,7 +7043,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data) break; } } - +#endif if (this->mTrueJump && this->mTrueJump->ValueForwarding(mNDataSet)) changed = true; if (this->mFalseJump && this->mFalseJump->ValueForwarding(mNDataSet)) @@ -7286,6 +7389,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) } #endif +#if 1 + // move load - store abs up to initial store + // + + for (int i = 2; i + 2 < mIns.Size(); i++) + { + if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE) + { + if (MoveAbsoluteLoadStoreUp(i)) + changed = true; + } + } +#endif + // // shorten x/y register livetime @@ -7674,80 +7791,93 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) if (i + 3 < mIns.Size()) { - if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && - 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 + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && - (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) - { - mIns[i + 0].mType = ASMIT_NOP; - mIns[i + 1].mType = ASMIT_NOP; - mIns[i + 2].mType = ASMIT_NOP; - mIns[i + 3].mType = ASMIT_INC; - progress = true; - } - else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && - mIns[i + 1].mType == ASMIT_SEC && mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 && - (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && - (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) - { - mIns[i + 0].mType = ASMIT_NOP; - mIns[i + 1].mType = ASMIT_NOP; - mIns[i + 2].mType = ASMIT_NOP; - mIns[i + 3].mType = ASMIT_DEC; - progress = true; - } - else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && - mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress & 0xff) == 0xff && - (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && - (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) - { - mIns[i + 0].mType = ASMIT_NOP; - mIns[i + 1].mType = ASMIT_NOP; - mIns[i + 2].mType = ASMIT_NOP; - mIns[i + 3].mType = ASMIT_DEC; - progress = true; - } - else if ( - mIns[i + 0].mType == ASMIT_LDA && - mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && - mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress && - mIns[i + 3].mType == ASMIT_CMP && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress && !(mIns[i + 3].mLive & LIVE_MEM)) - { - mIns[i + 3].mMode = mIns[i + 0].mMode; - mIns[i + 3].mAddress = mIns[i + 0].mAddress; - mIns[i + 3].mLinkerObject = mIns[i + 0].mLinkerObject; - - progress = true; - } -#if 0 - if ( - mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && - mIns[i + 1].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && - !mIns[i + 2].ChangesYReg() && (mIns[i + 2].mMode == ASMIM_IMMEDIATE || mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress) && - mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mAddress == mIns[i + 3].mAddress && !(mIns[i + 3].mLive & LIVE_MEM)) - { - int apos, breg, ireg; - if (FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg)) + if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && + 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 + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && + (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) { - if (breg == mIns[i + 1].mAddress) - { - mIns[apos + 3].mType = ASMIT_NOP; - mIns[apos + 3].mMode = ASMIM_IMPLIED; - mIns[apos + 6].mType = ASMIT_NOP; - mIns[apos + 6].mMode = ASMIM_IMPLIED; - } - if (mIns[i + 3].mLive & LIVE_CPU_REG_Y) - { - mIns.Insert(i + 4, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); - mIns[i + 4].mLive |= LIVE_CPU_REG_Y; - } - mIns[i + 0].mMode = ASMIM_ZERO_PAGE; - mIns[i + 0].mAddress = ireg; - mIns[i + 1].mAddress = breg; - mIns[i + 3].mAddress = breg; + mIns[i + 0].mType = ASMIT_NOP; + mIns[i + 1].mType = ASMIT_NOP; + mIns[i + 2].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_INC; progress = true; } - } + else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && + mIns[i + 1].mType == ASMIT_SEC && mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == 1 && + (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && + (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) + { + mIns[i + 0].mType = ASMIT_NOP; + mIns[i + 1].mType = ASMIT_NOP; + mIns[i + 2].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_DEC; + progress = true; + } + else if (mIns[i + 0].mType == ASMIT_LDA && mIns[i + 3].mType == ASMIT_STA && mIns[i + 0].SameEffectiveAddress(mIns[i + 3]) && + mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && (mIns[i + 2].mAddress & 0xff) == 0xff && + (mIns[i + 0].mMode == ASMIM_ABSOLUTE || mIns[i + 0].mMode == ASMIM_ZERO_PAGE) && + (mIns[i + 3].mLive & (LIVE_CPU_REG_C | LIVE_CPU_REG_A)) == 0) + { + mIns[i + 0].mType = ASMIT_NOP; + mIns[i + 1].mType = ASMIT_NOP; + mIns[i + 2].mType = ASMIT_NOP; + mIns[i + 3].mType = ASMIT_DEC; + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_LDA && + mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress && + mIns[i + 3].mType == ASMIT_CMP && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress && !(mIns[i + 3].mLive & LIVE_MEM)) + { + mIns[i + 3].mMode = mIns[i + 0].mMode; + mIns[i + 3].mAddress = mIns[i + 0].mAddress; + mIns[i + 3].mLinkerObject = mIns[i + 0].mLinkerObject; + + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_LDX && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && + mIns[i + 3].mType == ASMIT_STX && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && + !mIns[i + 1].ChangesZeroPage(mIns[i + 0].mAddress) && !mIns[i + 1].UsesZeroPage(mIns[i + 3].mAddress)) + { + mIns.Insert(i + 1, NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, mIns[i + 3].mAddress)); + + mIns[i + 4].mType = ASMIT_NOP; + mIns[i + 4].mMode = ASMIM_IMPLIED; + + progress = true; + } +#if 0 + if ( + mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && + !mIns[i + 2].ChangesYReg() && (mIns[i + 2].mMode == ASMIM_IMMEDIATE || mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 1].mAddress) && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_INDIRECT_Y && mIns[i + 1].mAddress == mIns[i + 3].mAddress && !(mIns[i + 3].mLive & LIVE_MEM)) + { + int apos, breg, ireg; + if (FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg)) + { + if (breg == mIns[i + 1].mAddress) + { + mIns[apos + 3].mType = ASMIT_NOP; + mIns[apos + 3].mMode = ASMIM_IMPLIED; + mIns[apos + 6].mType = ASMIT_NOP; + mIns[apos + 6].mMode = ASMIM_IMPLIED; + } + if (mIns[i + 3].mLive & LIVE_CPU_REG_Y) + { + mIns.Insert(i + 4, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + mIns[i + 4].mLive |= LIVE_CPU_REG_Y; + } + mIns[i + 0].mMode = ASMIM_ZERO_PAGE; + mIns[i + 0].mAddress = ireg; + mIns[i + 1].mAddress = breg; + mIns[i + 3].mAddress = breg; + progress = true; + } + } #endif @@ -8353,7 +8483,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) if (entryBlock->JoinTailCodeSequences()) changed = true; } - +#if 1 ResetVisited(); NativeRegisterDataSet data; entryBlock->BuildEntryDataSet(data); @@ -8361,7 +8491,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) ResetVisited(); if (entryBlock->ApplyEntryDataSet()) changed = true; - +#endif if (!changed && step < 4) { step++; diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index c6a8b99..3b20294 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -72,6 +72,7 @@ public: bool RequiresYReg(void) const; bool ChangesYReg(void) const; bool ChangesZeroPage(int address) const; + bool UsesZeroPage(int address) const; bool ChangesGlobalMemory(void) const; bool SameEffectiveAddress(const NativeCodeInstruction& ins) const; bool IsSame(const NativeCodeInstruction& ins) const; @@ -156,6 +157,7 @@ public: bool MoveLoadStoreUp(int at); bool MoveIndirectLoadStoreUp(int at); + bool MoveAbsoluteLoadStoreUp(int at); bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg); bool FindGlobalAddress(int at, int reg, int& apos); bool FindGlobalAddressSumY(int at, int reg, const NativeCodeInstruction * & ains, int& ireg);