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.
iocharmap(IOCHM_PETSCII_2);
printf("Hello World\");
printf("Hello World\n");
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_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

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)
{
@ -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);

View File

@ -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
@ -7717,6 +7834,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
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
@ -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++;

View File

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