Fix optimizer errors

This commit is contained in:
drmortalwombat 2021-10-23 00:33:09 +02:00
parent c351c6521a
commit 33433403b1
7 changed files with 588 additions and 36 deletions

316
include/c64/rasterirq.c Normal file
View File

@ -0,0 +1,316 @@
#include "rasterirq.h"
#include <c64/vic.h>
#include <c64/cia.h>
volatile char npos = 1, tpos = 0;
byte rasterIRQRows[NUM_IRQS];
byte rasterIRQIndex[NUM_IRQS];
byte rasterIRQNext[NUM_IRQS];
byte rasterIRQLow[NUM_IRQS];
byte rasterIRQHigh[NUM_IRQS];
byte nextIRQ;
__asm irq0
{
pha
txa
pha
tya
pha
ldx nextIRQ
l1:
lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex, x
tax
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji:
jsr $0000
jx:
inc nextIRQ
ldx nextIRQ
lda rasterIRQNext, x
cmp #$ff
beq e2
tay
sec
sbc #4
cmp $d012
bcc l1
dey
sty $d012
w1:
jmp ex
e2:
sta $d012
lda npos
sta tpos
asl $d019
jmp ex
e1:
ldx #0
stx nextIRQ
lda rasterIRQNext, x
sec
sbc #1
sta $d012
ex:
asl $d019
pla
tay
pla
tax
pla
rti
}
__asm irq1
{
ldx nextIRQ
l1:
lda rasterIRQNext, x
cmp #$ff
beq e1
ldy rasterIRQIndex, x
tax
lda rasterIRQLow, y
sta ji + 1
lda rasterIRQHigh, y
sta ji + 2
ji:
jsr $0000
jx:
inc nextIRQ
ldx nextIRQ
lda rasterIRQNext, x
cmp #$ff
beq e2
tay
sec
sbc #4
cmp $d012
bcc l1
dey
sty $d012
w1:
jmp ex
e2:
sta $d012
lda npos
sta tpos
asl $d019
jmp ex
e1:
ldx #0
stx nextIRQ
lda rasterIRQNext, x
sec
sbc #1
sta $d012
ex:
asl $d019
jmp $ea31
}
// 0 lda #data0
// 2 ldy #data1
// 4 cpx $d012
// 7 bcc -5
// 9 sta addr0
// 12 sty addr1
// 15 lda #data2
// 17 sta addr2
// 20 lda #data3
// 22 sta addr3
// ...
// rts
void rirq_build(RIRQCode * ic, byte size)
{
ic->size = size;
ic->code[0] = 0xa9; // lda #
ic->code[2] = 0xa0; // ldy #
ic->code[4] = 0xec; // cpx
ic->code[5] = 0x12;
ic->code[6] = 0xd0;
ic->code[7] = 0xb0; // bcs
ic->code[8] = -5;
ic->code[9] = 0x8d; // sta
if (size == 1)
{
ic->code[12] = 0x60; // rts
}
else
{
ic->code[12] = 0x8c; // sty
byte p = 15;
for(byte i=2; i<size; i++)
{
ic->code[p] = 0xa9; // lda #
ic->code[p + 2] = 0x8d; // sta
p += 5;
}
ic->code[p] = 0x60;
}
}
void rirq_set(byte n, byte row, RIRQCode * write)
{
rasterIRQLow[n] = (unsigned)&write->code & 0xff;
rasterIRQHigh[n] = (unsigned)&write->code >> 8;
rasterIRQRows[n] = row;
}
static const byte irqai[6] = {RIRQ_ADDR_0, RIRQ_ADDR_1, RIRQ_ADDR_2, RIRQ_ADDR_3, RIRQ_ADDR_4};
static const byte irqdi[6] = {RIRQ_DATA_0, RIRQ_DATA_1, RIRQ_DATA_2, RIRQ_DATA_3, RIRQ_DATA_4};
void rirq_addr(RIRQCode * ic, byte n, void * addr)
{
byte p = irqai[n];
ic->code[p + 0] = (unsigned)addr & 0xff;
ic->code[p + 1] = (unsigned)addr >> 8;
}
void rirq_data(RIRQCode * ic, byte n, byte data)
{
byte p = irqdi[n];
ic->code[p] = data;
}
void rirq_write(RIRQCode * ic, byte n, void * addr, byte data)
{
byte p = irqai[n];
ic->code[p + 0] = (unsigned)addr & 0xff;
ic->code[p + 1] = (unsigned)addr >> 8;
p = irqdi[n];
ic->code[p] = data;
}
void rirq_move(byte n, byte row)
{
rasterIRQRows[n] = row;
}
void rirq_clear(byte n)
{
rasterIRQRows[n] = 255;
}
void rirq_init(bool kernalIRQ)
{
for(byte i=0; i<NUM_IRQS; i++)
{
rasterIRQRows[i] = 255;
rasterIRQIndex[i] = i;
}
__asm
{
sei
// disable CIA interrupts
lda #$7f
sta $dc0d
sta $dd0d
}
if (kernalIRQ)
*(void **)0x0314 = irq1;
else
*(void **)0xfffe = irq0;
vic.intr_enable = 1;
vic.ctrl1 &= 0x7f;
vic.raster = 255;
}
void rirq_wait(void)
{
while (tpos != npos) ;
}
void rirq_sort(void)
{
for(byte i = 1; i<NUM_IRQS; i++)
{
byte ri = rasterIRQIndex[i];
byte rr = rasterIRQRows[ri];
byte j = i, rj = rasterIRQIndex[j - 1];
while (j > 0 && rr < rasterIRQRows[rj])
{
rasterIRQIndex[j] = rj;
j--;
rj = rasterIRQIndex[j - 1]
}
rasterIRQIndex[j] = ri;
}
for(byte i=0; i<NUM_IRQS; i++)
rasterIRQNext[i] = rasterIRQRows[rasterIRQIndex[i]];
npos++;
}
void rirq_start(void)
{
__asm
{
lda $d011
and #$7f
sta $d011
lda #100
sta $d012
cli
}
}
void rirq_stop(void)
{
__asm
{
sei
}
}

54
include/c64/rasterirq.h Normal file
View File

@ -0,0 +1,54 @@
#ifndef C64_RASTERIRQ_H
#define C64_RASTERIRQ_H
#include "types.h"
#define NUM_IRQS 16
enum RIRQCodeIndex
{
RIRQ_DATA_0 = 1,
RIRQ_DATA_1 = 3,
RIRQ_ADDR_0 = 10,
RIRQ_ADDR_1 = 13,
RIRQ_DATA_2 = 16,
RIRQ_ADDR_2 = 18,
RIRQ_DATA_3 = 21,
RIRQ_ADDR_3 = 23,
RIRQ_DATA_4 = 26,
RIRQ_ADDR_4 = 28,
RIRQ_SIZE = 31
};
struct RIRQCode
{
byte size;
byte code[RIRQ_SIZE];
};
void rirq_build(RIRQCode * ic, byte size);
inline void rirq_write(RIRQCode * ic, byte n, void * addr, byte data);
inline void rirq_addr(RIRQCode * ic, byte n, void * addr);
inline void rirq_data(RIRQCode * ic, byte n, byte data);
inline void rirq_set(byte n, byte row, RIRQCode * write);
inline void rirq_clear(byte n)
inline void rirq_move(byte n, byte row);
void rirq_init(bool kernalIRQ);
void rirq_start(void);
void rirq_stop(void);
void rirq_sort(void);
void rirq_wait(void);
#pragma compile("rasterirq.c")
#endif

View File

@ -3260,14 +3260,14 @@ __asm inp_op_extrt
{ {
lda (ip), y lda (ip), y
iny iny
sta c1 + 1 sta _c1 + 1
lda (ip), y lda (ip), y
iny iny
sta c1 + 2 sta _c1 + 2
lda (ip), y lda (ip), y
iny iny
tax tax
c1: jsr $0000 _c1: jsr $0000
jmp startup.exec jmp startup.exec
} }

View File

@ -471,6 +471,9 @@ bool InterInstruction::IsEqual(const InterInstruction* ins) const
if (!mSrc[i].IsEqual(ins->mSrc[i])) if (!mSrc[i].IsEqual(ins->mSrc[i]))
return false; return false;
if (mCode == IC_CONSTANT && !mConst.IsEqual(ins->mConst))
return false;
return true; return true;
} }
@ -1845,6 +1848,7 @@ InterCodeBasicBlock::InterCodeBasicBlock(void)
{ {
mInPath = false; mInPath = false;
mLoopHead = false; mLoopHead = false;
mChecked = false;
} }
InterCodeBasicBlock::~InterCodeBasicBlock(void) InterCodeBasicBlock::~InterCodeBasicBlock(void)
@ -1884,15 +1888,23 @@ void InterCodeBasicBlock::CollectEntries(void)
} }
} }
static bool IsInfiniteLoop(const InterCodeBasicBlock* block) static bool IsInfiniteLoop(InterCodeBasicBlock* head, InterCodeBasicBlock* block)
{ {
const InterCodeBasicBlock* nblock = block; if (!block->mChecked)
while (nblock->mTrueJump && !nblock->mFalseJump)
{ {
nblock = nblock->mTrueJump; if (block->mTrueJump && !block->mFalseJump)
if (nblock == block) {
if (block->mTrueJump == head)
return true; return true;
block->mChecked = true;
bool loop = IsInfiniteLoop(head, block->mTrueJump);
block->mChecked = false;
return loop;
} }
}
return false; return false;
} }
@ -1924,7 +1936,7 @@ void InterCodeBasicBlock::GenerateTraces(bool expand)
if (mFalseJump) if (mFalseJump)
mFalseJump->mNumEntries++; mFalseJump->mNumEntries++;
} }
else if (mTrueJump && !mFalseJump && ((expand && mTrueJump->mInstructions.Size() < 10 && mTrueJump->mInstructions.Size() > 1) || mTrueJump->mNumEntries == 1) && !mTrueJump->mLoopHead && !IsInfiniteLoop(mTrueJump)) else if (mTrueJump && !mFalseJump && ((expand && mTrueJump->mInstructions.Size() < 10 && mTrueJump->mInstructions.Size() > 1) || mTrueJump->mNumEntries == 1) && !mTrueJump->mLoopHead && !IsInfiniteLoop(mTrueJump, mTrueJump))
{ {
mTrueJump->mNumEntries--; mTrueJump->mNumEntries--;
@ -2140,6 +2152,33 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
ins->mSrc[1].mIntConst = tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst; ins->mSrc[1].mIntConst = tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst;
ins->mSrc[1].mOperandSize = tvalue[ins->mSrc[1].mTemp]->mConst.mOperandSize; ins->mSrc[1].mOperandSize = tvalue[ins->mSrc[1].mTemp]->mConst.mOperandSize;
ins->mSrc[1].mTemp = -1; ins->mSrc[1].mTemp = -1;
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_BINARY_OPERATOR)
{
InterInstruction* iins = tvalue[ins->mSrc[0].mTemp];
if (iins->mOperator == IA_ADD)
{
if (iins->mSrc[0].mTemp >= 0 && iins->mSrc[1].mTemp < 0)
{
ins->mSrc[0].mTemp = iins->mSrc[0].mTemp;
ins->mSrc[1].mIntConst += iins->mSrc[1].mIntConst;
}
else if (iins->mSrc[0].mTemp < 0 && iins->mSrc[1].mTemp >= 0)
{
ins->mSrc[0].mTemp = iins->mSrc[1].mTemp;
ins->mSrc[1].mIntConst += iins->mSrc[0].mIntConst;
}
}
else if (iins->mOperator == IA_SUB)
{
if (iins->mSrc[0].mTemp < 0 && iins->mSrc[1].mTemp >= 0)
{
ins->mSrc[0].mTemp = iins->mSrc[1].mTemp;
ins->mSrc[1].mIntConst -= iins->mSrc[0].mIntConst;
}
}
}
} }
break; break;
case IC_TYPECAST: case IC_TYPECAST:

View File

@ -408,7 +408,7 @@ public:
InterCodeBasicBlock * mTrueJump, * mFalseJump, * mDominator; InterCodeBasicBlock * mTrueJump, * mFalseJump, * mDominator;
GrowingInstructionArray mInstructions; GrowingInstructionArray mInstructions;
bool mVisited, mInPath, mLoopHead; bool mVisited, mInPath, mLoopHead, mChecked;
NumberSet mLocalRequiredTemps, mLocalProvidedTemps; NumberSet mLocalRequiredTemps, mLocalProvidedTemps;
NumberSet mEntryRequiredTemps, mEntryProvidedTemps; NumberSet mEntryRequiredTemps, mEntryProvidedTemps;

View File

@ -515,6 +515,11 @@ bool NativeCodeInstruction::ChangesYReg(void) const
return mType == ASMIT_TAY || mType == ASMIT_LDY || mType == ASMIT_INY || mType == ASMIT_DEY || mType == ASMIT_JSR; return mType == ASMIT_TAY || mType == ASMIT_LDY || mType == ASMIT_INY || mType == ASMIT_DEY || mType == ASMIT_JSR;
} }
bool NativeCodeInstruction::ChangesXReg(void) const
{
return mType == ASMIT_TAX || mType == ASMIT_LDX || mType == ASMIT_INX || mType == ASMIT_DEX || mType == ASMIT_JSR;
}
bool NativeCodeInstruction::ChangesZeroPage(int address) const bool NativeCodeInstruction::ChangesZeroPage(int address) const
{ {
if (mMode == ASMIM_ZERO_PAGE && mAddress == address) if (mMode == ASMIM_ZERO_PAGE && mAddress == address)
@ -1888,6 +1893,21 @@ void NativeCodeInstruction::FilterRegUsage(NumberSet& requiredTemps, NumberSet&
providedTemps += BC_REG_ADDR + i; providedTemps += BC_REG_ADDR + i;
} }
if (!(mFlags & NCIF_RUNTIME))
{
if (mLinkerObject)
{
for (int i = 0; i < mLinkerObject->mNumTemporaries; i++)
{
for (int j = 0; j < mLinkerObject->mTempSizes[i]; j++)
{
if (!providedTemps[mLinkerObject->mTemporaries[i] + j])
requiredTemps += mLinkerObject->mTemporaries[i] + j;
}
}
}
}
providedTemps += CPU_REG_A; providedTemps += CPU_REG_A;
providedTemps += CPU_REG_X; providedTemps += CPU_REG_X;
providedTemps += CPU_REG_Y; providedTemps += CPU_REG_Y;
@ -4806,8 +4826,15 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg));
if (InterTypeSize[ins->mDst.mType] > 1) if (InterTypeSize[ins->mDst.mType] > 1)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, 2)); NativeCodeBasicBlock* iblock = nproc->AllocateBlock();
mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg + 1)); NativeCodeBasicBlock* eblock = nproc->AllocateBlock();
this->Close(eblock, iblock, ASMIT_BNE);
iblock->mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg + 1));
iblock->Close(eblock, nullptr, ASMIT_JMP);
return eblock;
} }
} }
else if (ins->mOperator == IA_ADD && InterTypeSize[ins->mDst.mType] == 1 && ( else if (ins->mOperator == IA_ADD && InterTypeSize[ins->mDst.mType] == 1 && (
@ -4882,6 +4909,33 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
else else
{ {
if (sins1 && sins0) if (sins1 && sins0)
{
if (sins0->mSrc[0].mMemory == IM_INDIRECT && sins1->mSrc[0].mMemory == IM_INDIRECT && sins0->mSrc[0].mIntConst < 255 && sins1->mSrc[0].mIntConst < 255)
{
if (ins->mOperator == IA_ADD)
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, sins0->mSrc[0].mIntConst + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[sins0->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, sins1->mSrc[0].mIntConst + 0));
mIns.Push(NativeCodeInstruction(atype, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[sins1->mSrc[0].mTemp]));
if (InterTypeSize[ins->mDst.mType] > 1)
{
if (ins->mDst.mTemp == sins0->mSrc[0].mTemp || ins->mDst.mTemp == sins1->mSrc[0].mTemp)
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
else
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, sins0->mSrc[0].mIntConst + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[sins0->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, sins1->mSrc[0].mIntConst + 1));
mIns.Push(NativeCodeInstruction(atype, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[sins1->mSrc[0].mTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1));
if (ins->mDst.mTemp == sins0->mSrc[0].mTemp || ins->mDst.mTemp == sins1->mSrc[0].mTemp)
mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, treg));
}
else
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
}
else
{ {
insl = NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, treg); insl = NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, treg);
insh = NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, treg + 1); insh = NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, treg + 1);
@ -4897,6 +4951,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
LoadValueToReg(proc, sins1, treg, &insl, &insh); LoadValueToReg(proc, sins1, treg, &insl, &insh);
} }
} }
}
else if (sins1) else if (sins1)
{ {
insl = NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]); insl = NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]);
@ -6389,7 +6444,7 @@ void NativeCodeBasicBlock::CallFunction(InterCodeProcedure* proc, NativeCodeProc
} }
} }
void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction * ins) void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInstruction* ins)
{ {
if (ins->mCode == IC_ASSEMBLER) if (ins->mCode == IC_ASSEMBLER)
{ {
@ -6408,6 +6463,7 @@ void NativeCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterIn
} }
assert(ins->mSrc[0].mLinkerObject); assert(ins->mSrc[0].mLinkerObject);
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject)); mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject));
if (ins->mDst.mTemp >= 0) if (ins->mDst.mTemp >= 0)
@ -6820,7 +6876,7 @@ bool NativeCodeBasicBlock::FindGlobalAddress(int at, int reg, int& apos)
return false; return false;
} }
bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, const NativeCodeInstruction*& ains, int& ireg) bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction*& ains, int& ireg)
{ {
int j = at - 7; int j = at - 7;
while (j >= 0) while (j >= 0)
@ -6835,17 +6891,53 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, const NativeCo
{ {
ains = &(mIns[j + 1]); ains = &(mIns[j + 1]);
ireg = mIns[j + 2].mAddress; ireg = mIns[j + 2].mAddress;
apos = j + 0;
if (reg == ireg && !direct)
return false;
int k = j + 7; int k = j + 7;
while (k < at) while (k < at)
{ {
if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress()) if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress())
return false; return false;
if (reg == ireg && mIns[k].ChangesYReg())
return false;
k++; k++;
} }
return true; return true;
} }
else if (
mIns[j + 0].mType == ASMIT_STA && mIns[j + 0].mMode == ASMIM_ZERO_PAGE &&
mIns[j + 1].mType == ASMIT_CLC &&
mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[j + 2].mFlags & NCIF_LOWER) && mIns[j + 2].mLinkerObject &&
mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg &&
mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[j + 4].mFlags & NCIF_UPPER) && mIns[j + 4].mLinkerObject == mIns[j + 2].mLinkerObject &&
mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 &&
mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1)
{
ains = &(mIns[j + 2]);
ireg = mIns[j + 0].mAddress;
apos = j + 1;
if (reg == ireg && !direct)
return false;
int k = j + 7;
while (k < at)
{
if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress())
return false;
if (reg == ireg && mIns[k].ChangesYReg())
return false;
k++;
}
return true;
}
if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1) && mIns[j + 6].ChangesAddress()) if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1) && mIns[j + 6].ChangesAddress())
return false; return false;
@ -6860,7 +6952,7 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, const NativeCo
return false; return false;
j--; j--;
} }
if (mFromJump->FindGlobalAddressSumY(mFromJump->mIns.Size(), reg, ains, ireg)) if (mFromJump->FindGlobalAddressSumY(mFromJump->mIns.Size(), reg, false, apos, ains, ireg))
{ {
int k = 0; int k = 0;
while (k < at) while (k < at)
@ -6876,6 +6968,7 @@ bool NativeCodeBasicBlock::FindGlobalAddressSumY(int at, int reg, const NativeCo
return false; return false;
} }
bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg) bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg)
{ {
int j = at - 7; int j = at - 7;
@ -6958,6 +7051,7 @@ bool NativeCodeBasicBlock::MoveAbsoluteLoadStoreUp(int at)
{ {
if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress) if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress)
{ {
mIns[j].mLive |= LIVE_CPU_REG_A;
mIns.Insert(j + 1, mIns[at + 1]); mIns.Insert(j + 1, mIns[at + 1]);
mIns[at + 2].mType = ASMIT_NOP; mIns[at + 2].mType = ASMIT_NOP;
mIns[at + 2].mMode = ASMIM_IMPLIED; mIns[at + 2].mMode = ASMIM_IMPLIED;
@ -6998,6 +7092,7 @@ bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
{ {
mIns[i] = mIns[i - 1]; mIns[i] = mIns[i - 1];
} }
mIns[j - 1].mLive |= LIVE_CPU_REG_A;
mIns[j] = mIns[at + 1]; mIns[j] = mIns[at + 1];
mIns[at + 1].mType = ASMIT_NOP; mIns[at + 1].mType = ASMIT_NOP;
@ -7463,7 +7558,6 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mVisited = true; mVisited = true;
#if 1 #if 1
// move load store pairs up to initial store // move load store pairs up to initial store
@ -7602,8 +7696,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
{ {
const NativeCodeInstruction* ains; const NativeCodeInstruction* ains;
int sreg = mIns[i + 0].mAddress;
int apos, breg, ireg; int apos, breg, ireg;
if (FindAddressSumY(i, mIns[i + 0].mAddress, apos, breg, ireg)) if (FindAddressSumY(i, sreg, apos, breg, ireg))
{ {
if (breg != mIns[i + 0].mAddress || !(mIns[i + 0].mLive & LIVE_MEM)) if (breg != mIns[i + 0].mAddress || !(mIns[i + 0].mLive & LIVE_MEM))
{ {
@ -7625,7 +7721,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
progress = true; progress = true;
} }
} }
else if (FindGlobalAddressSumY(i, mIns[i + 0].mAddress, ains, ireg)) else if (FindGlobalAddressSumY(i, sreg, true, apos, ains, ireg))
{ {
if (mIns[i + 0].mLive & LIVE_CPU_REG_Y) if (mIns[i + 0].mLive & LIVE_CPU_REG_Y)
{ {
@ -7633,11 +7729,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 1].mLive |= LIVE_CPU_REG_Y; mIns[i + 1].mLive |= LIVE_CPU_REG_Y;
} }
mIns[i + 0].mMode = ASMIM_ABSOLUTE_Y;
mIns[i + 0].mLinkerObject = ains->mLinkerObject;
mIns[i + 0].mAddress = ains->mAddress;
mIns[i + 0].mFlags &= ~NCIF_YZERO;
if (ireg == sreg)
mIns.Insert(apos, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
else
mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg)); mIns.Insert(i + 0, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y;
mIns[i + 1].mLinkerObject = ains->mLinkerObject;
mIns[i + 1].mAddress = ains->mAddress;
mIns[i + 1].mFlags &= ~NCIF_YZERO;
progress = true; progress = true;
} }
@ -7762,6 +7862,38 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 0].mType = ASMIT_LDA; mIns[i + 0].mType = ASMIT_LDA;
progress = true; progress = true;
} }
else if (mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mMode == ASMIM_INDIRECT_Y)
{
const NativeCodeInstruction* ains;
int sreg = mIns[i + 1].mAddress;
int apos, ireg;
if (FindGlobalAddressSumY(i, sreg, true, apos, ains, ireg))
{
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
{
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, mIns[i + 0].mAddress));
mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
}
mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y;
mIns[i + 1].mLinkerObject = ains->mLinkerObject;
mIns[i + 1].mAddress = ains->mAddress + mIns[i + 0].mAddress;
if (ireg == sreg)
{
mIns[i + 0].mType = ASMIT_NOP;
mIns.Insert(apos, NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, ireg));
}
else
{
mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
mIns[i + 0].mAddress = ireg;
}
progress = true;
}
}
} }
@ -7909,6 +8041,13 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
progress = true; progress = true;
} }
#endif #endif
else if (
mIns[i + 0].mType == ASMIT_TAX &&
!mIns[i + 1].ChangesXReg() &&
mIns[i + 2].mType == ASMIT_TXA && !(mIns[i + 2].mLive & LIVE_CPU_REG_Z))
{
mIns[i + 2].mType = ASMIT_NOP;
}
#if 1 #if 1
if ( if (
mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
@ -8636,6 +8775,8 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
bool changed; bool changed;
do do
{ {
changed = false;
ResetVisited(); ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++) for (int i = 0; i < mBlocks.Size(); i++)
{ {
@ -8646,6 +8787,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
} }
entryBlock->CountEntries(nullptr); entryBlock->CountEntries(nullptr);
#if 1
do do
{ {
BuildDataFlowSets(); BuildDataFlowSets();
@ -8658,7 +8800,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
changed = true; changed = true;
} while (changed); } while (changed);
#endif
ResetVisited(); ResetVisited();
if (entryBlock->PeepHoleOptimizer()) if (entryBlock->PeepHoleOptimizer())
changed = true; changed = true;

View File

@ -73,6 +73,7 @@ public:
bool RequiresAccu(void) const; bool RequiresAccu(void) const;
bool RequiresYReg(void) const; bool RequiresYReg(void) const;
bool ChangesYReg(void) const; bool ChangesYReg(void) const;
bool ChangesXReg(void) const;
bool ChangesZeroPage(int address) const; bool ChangesZeroPage(int address) const;
bool UsesZeroPage(int address) const; bool UsesZeroPage(int address) const;
bool ChangesGlobalMemory(void) const; bool ChangesGlobalMemory(void) const;
@ -164,7 +165,7 @@ public:
bool MoveLoadAddImmStoreUp(int at); bool MoveLoadAddImmStoreUp(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, bool direct, int& apos, const NativeCodeInstruction * & ains, int& ireg);
bool ValueForwarding(const NativeRegisterDataSet& data); bool ValueForwarding(const NativeRegisterDataSet& data);