Fix 16 bit pointer offsets in native code

This commit is contained in:
drmortalwombat 2021-10-13 22:19:27 +02:00
parent 5372d49b50
commit 3c891fb61e
7 changed files with 361 additions and 142 deletions

View File

@ -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. 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); iocharmap(IOCHM_PETSCII_2);
printf("Hello World\"); printf("Hello World\n");
Will switch to the lowercase PETSCII font and translate the strings while printing. Will switch to the lowercase PETSCII font and translate the strings while printing.

23
include/c64/cia.h Normal file
View File

@ -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

7
include/c64/vic.c Normal file
View File

@ -0,0 +1,7 @@
#include "vic.h"
#include "cia.h"
void vic_setbank(char bank)
{
cia2.pra = (cia2.pra & 0xfc) | (bank ^ 0x03);
}

View File

@ -9,9 +9,9 @@
#define VIC_CTRL1_ECM 0x40 #define VIC_CTRL1_ECM 0x40
#define VIC_CTRL1_RST8 0x80 #define VIC_CTRL1_RST8 0x80
#define VIC_CTRL2_CSEL 0x10 #define VIC_CTRL2_CSEL 0x08
#define VIC_CTRL2_MCM 0x20 #define VIC_CTRL2_MCM 0x10
#define VIC_CTRL2_RES 0x40 #define VIC_CTRL2_RES 0x20
#define VIC_INTR_RST 0x01 #define VIC_INTR_RST 0x01
#define VIC_INTR_MBC 0x02 #define VIC_INTR_MBC 0x02
@ -45,7 +45,7 @@ struct VIC
struct XY struct XY
{ {
byte x, y; byte x, y;
} spritexy[8]; } spr_pos[8];
byte spr_msbx; byte spr_msbx;
byte ctrl1; byte ctrl1;
@ -73,6 +73,10 @@ struct VIC
}; };
void vic_setbank(char bank);
#define vic (*((VIC *)0xd000)) #define vic (*((VIC *)0xd000))
#pragma compile("vic.c")
#endif #endif

View File

@ -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) switch (oper)
{ {
@ -3357,6 +3357,27 @@ static bool CanBypassLoad(const InterInstruction * lins, const InterInstruction
return true; 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) static bool CanBypassStore(const InterInstruction * sins, const InterInstruction * bins)
{ {
if (bins->mCode == IC_COPY || bins->mCode == IC_PUSH_FRAME) 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) void InterCodeBasicBlock::PeepholeOptimization(void)
{ {
int i; int i;
@ -3629,7 +3654,7 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
// shorten lifespan // shorten lifespan
int limit = mInstructions.Size() - 1; int limit = mInstructions.Size() - 1;
if (limit >= 2 && mInstructions[limit]->mCode == IC_BRANCH) if (limit >= 0 && mInstructions[limit]->mCode == IC_BRANCH)
limit -= 2; limit -= 2;
int i = limit; int i = limit;
@ -3649,6 +3674,18 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
if (i != j) if (i != j)
mInstructions[j] = ins; 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--; 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 + 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) (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 + 0]->mDst.mTemp = mInstructions[i + 1]->mDst.mTemp;
mInstructions[i + 1]->mCode = IC_NONE; mInstructions[i + 1]->mCode = IC_NONE;
mInstructions[i + 2]->mSrc[0].mTemp = mInstructions[i + 1]->mDst.mTemp; mInstructions[i + 2]->mSrc[0].mTemp = mInstructions[i + 1]->mDst.mTemp;
mInstructions[i + 2]->mSrc[0].mFinal = false; 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; changed = true;
} }
else if (mInstructions[i + 0]->mDst.mTemp >= 0 && 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; mInstructions[i + 1]->mSrc[0].mTemp = mInstructions[i + 0]->mDst.mTemp;
changed = true; 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 // Postincrement artifact
if (mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && if (mInstructions[i + 0]->mCode == IC_LOAD_TEMPORARY && mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
@ -4390,11 +4443,11 @@ void InterCodeProcedure::Close(void)
ResetVisited(); ResetVisited();
mEntryBlock->PeepholeOptimization(); mEntryBlock->PeepholeOptimization();
DisassembleDebug("Peephole optimized");
TempForwarding(); TempForwarding();
RemoveUnusedInstructions(); RemoveUnusedInstructions();
DisassembleDebug("Peephole optimized");
ResetVisited(); ResetVisited();
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet); mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet);

View File

@ -523,6 +523,15 @@ bool NativeCodeInstruction::ChangesZeroPage(int address) const
return false; 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 bool NativeCodeInstruction::ChangesGlobalMemory(void) const
{ {
if (mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_ABSOLUTE || mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_ABSOLUTE_Y) 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; mType = ASMIT_LDA;
data.mRegs[CPU_REG_A].Reset(); data.mRegs[CPU_REG_A].Reset();
data.mRegs[CPU_REG_Z].Reset();
} }
else else
{ {
mType = ASMIT_LDA; mType = ASMIT_LDA;
mMode = ASMIM_IMMEDIATE; mMode = ASMIM_IMMEDIATE;
mAddress = 0; mAddress = 0;
data.mRegs[CPU_REG_Z].mMode = NRDM_IMMEDIATE;
data.mRegs[CPU_REG_Z].mValue = 0;
} }
changed = true; changed = true;
} }
@ -2540,36 +2553,46 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
{ {
if (ins->mSrc[1].mMemory == IM_INDIRECT) 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_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_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); 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_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 16) & 0xff)); 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_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff)); 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 else
{ {
if (ins->mSrc[1].mMemory == IM_INDIRECT) 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_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_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_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_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_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_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_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) 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_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_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); 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 else
{ {
if (ins->mSrc[1].mMemory == IM_INDIRECT) 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_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_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_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) 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_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) if (InterTypeSize[ins->mSrc[0].mType] == 2)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); 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) else if (InterTypeSize[ins->mSrc[0].mType] == 4)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); 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_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 16) & 0xff)); 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_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff)); 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) 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_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) if (InterTypeSize[ins->mSrc[0].mType] == 2)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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_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) else if (InterTypeSize[ins->mSrc[0].mType] == 4)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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_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_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_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_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_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) if (rins->mSrc[0].mMemory == IM_INDIRECT)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rins->mSrc[0].mIntConst)); int areg = BC_REG_TMP + proc->mTempOffset[rins->mSrc[0].mTemp];
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, 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) if (wins->mSrc[1].mMemory == IM_INDIRECT)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, wins->mSrc[1].mIntConst)); int areg = BC_REG_TMP + proc->mTempOffset[wins->mSrc[1].mTemp];
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, 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) if (ins->mSrc[0].mMemory == IM_INDIRECT)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst)); int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, 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_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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)); 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) if (ins->mSrc[0].mMemory == IM_INDIRECT)
{ {
int src = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst)); int index = ins->mSrc[0].mIntConst;
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src));
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)
{ {
if (ainsl->mType == ASMIT_ADC) 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(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
mIns.Push(*ainsl); mIns.Push(*ainsl);
} }
if (reg == src) if (reg == areg)
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
else else
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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); if (ainsh) mIns.Push(*ainsh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); 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)); 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) 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) if (InterTypeSize[ins->mDst.mType] == 1)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
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));
if (ainsl) if (ainsl)
{ {
if (ainsl->mType == ASMIT_ADC) if (ainsl->mType == ASMIT_ADC)
@ -3698,10 +3767,8 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
} }
else if (InterTypeSize[ins->mDst.mType] == 2) 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, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src));
if (ainsl) if (ainsl)
{ {
if (ainsl->mType == ASMIT_ADC) if (ainsl->mType == ASMIT_ADC)
@ -3713,16 +3780,16 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
if (InterTypeSize[ins->mDst.mType] > 1) if (InterTypeSize[ins->mDst.mType] > 1)
{ {
if (reg == src) if (reg == areg)
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
else else
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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); if (ainsh) mIns.Push(*ainsh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); 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)); mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, reg));
} }
else else
@ -3730,20 +3797,18 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
} }
else if (InterTypeSize[ins->mDst.mType] == 4) 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, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); 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)); 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_ASL, ASMIM_ZERO_PAGE, reg + 0));
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, reg + 1)); 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 else
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 1));
@ -6803,6 +6882,29 @@ bool NativeCodeBasicBlock::MoveIndirectLoadStoreUp(int at)
return false; 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) bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
{ {
int j = at; int j = at;
@ -6874,6 +6976,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data)
changed = true; changed = true;
} }
#if 1
if (mFalseJump) if (mFalseJump)
{ {
switch (mBranch) switch (mBranch)
@ -6940,7 +7043,7 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data)
break; break;
} }
} }
#endif
if (this->mTrueJump && this->mTrueJump->ValueForwarding(mNDataSet)) if (this->mTrueJump && this->mTrueJump->ValueForwarding(mNDataSet))
changed = true; changed = true;
if (this->mFalseJump && this->mFalseJump->ValueForwarding(mNDataSet)) if (this->mFalseJump && this->mFalseJump->ValueForwarding(mNDataSet))
@ -7286,6 +7389,20 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
} }
#endif #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 // shorten x/y register livetime
@ -7717,6 +7834,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 3].mAddress = mIns[i + 0].mAddress; mIns[i + 3].mAddress = mIns[i + 0].mAddress;
mIns[i + 3].mLinkerObject = mIns[i + 0].mLinkerObject; 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; progress = true;
} }
#if 0 #if 0
@ -8353,7 +8483,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
if (entryBlock->JoinTailCodeSequences()) if (entryBlock->JoinTailCodeSequences())
changed = true; changed = true;
} }
#if 1
ResetVisited(); ResetVisited();
NativeRegisterDataSet data; NativeRegisterDataSet data;
entryBlock->BuildEntryDataSet(data); entryBlock->BuildEntryDataSet(data);
@ -8361,7 +8491,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
ResetVisited(); ResetVisited();
if (entryBlock->ApplyEntryDataSet()) if (entryBlock->ApplyEntryDataSet())
changed = true; changed = true;
#endif
if (!changed && step < 4) if (!changed && step < 4)
{ {
step++; step++;

View File

@ -72,6 +72,7 @@ public:
bool RequiresYReg(void) const; bool RequiresYReg(void) const;
bool ChangesYReg(void) const; bool ChangesYReg(void) const;
bool ChangesZeroPage(int address) const; bool ChangesZeroPage(int address) const;
bool UsesZeroPage(int address) const;
bool ChangesGlobalMemory(void) const; bool ChangesGlobalMemory(void) const;
bool SameEffectiveAddress(const NativeCodeInstruction& ins) const; bool SameEffectiveAddress(const NativeCodeInstruction& ins) const;
bool IsSame(const NativeCodeInstruction& ins) const; bool IsSame(const NativeCodeInstruction& ins) const;
@ -156,6 +157,7 @@ public:
bool MoveLoadStoreUp(int at); bool MoveLoadStoreUp(int at);
bool MoveIndirectLoadStoreUp(int at); bool MoveIndirectLoadStoreUp(int at);
bool MoveAbsoluteLoadStoreUp(int at);
bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg); bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg);
bool FindGlobalAddress(int at, int reg, int& apos); bool FindGlobalAddress(int at, int reg, int& apos);
bool FindGlobalAddressSumY(int at, int reg, const NativeCodeInstruction * & ains, int& ireg); bool FindGlobalAddressSumY(int at, int reg, const NativeCodeInstruction * & ains, int& ireg);