More native code optimisations

This commit is contained in:
drmortalwombat 2021-09-09 20:23:59 +02:00
parent 83f5d634df
commit f08d847a64
8 changed files with 681 additions and 195 deletions

View File

@ -119,6 +119,34 @@ W1: asl accu
rts rts
} }
__asm mul16by8
{
lda #0
sta tmp + 2
sta tmp + 3
lda tmp
lsr
bcc L2
L1:
tax
clc
lda tmp + 2
adc accu
sta tmp + 2
lda tmp + 3
adc accu + 1
sta tmp + 3
txa
L2:
asl accu + 0
rol accu + 1
lsr
bcs L1
bne L2
rts
}
__asm divs16 __asm divs16
{ {
bit accu + 1 bit accu + 1
@ -159,6 +187,7 @@ L2: jsr divmod
} }
#pragma runtime(mul16, mul16); #pragma runtime(mul16, mul16);
#pragma runtime(mul16by8, mul16by8);
#pragma runtime(divu16, divmod); #pragma runtime(divu16, divmod);
#pragma runtime(modu16, divmod); #pragma runtime(modu16, divmod);
#pragma runtime(divs16, divs16); #pragma runtime(divs16, divs16);
@ -1827,11 +1856,14 @@ __asm faddsub
sta accu + 2 sta accu + 2
beq fas_aligned beq fas_aligned
W1: W1:
lsr accu + 2 lda accu + 2
L1:
lsr
ror accu + 1 ror accu + 1
ror accu ror accu
inx inx
bne W1 bne L1
sta accu + 2
lda tmp + 5 lda tmp + 5
sta tmp + 4 sta tmp + 4
jmp fas_aligned jmp fas_aligned
@ -1840,12 +1872,13 @@ fas_align2nd:
// check if second operand is below rounding // check if second operand is below rounding
cpx #24 cpx #24
bcs fas_done bcs fas_done
lda tmp + 2
L2: lsr tmp + 2 L2: lsr
ror tmp + 1 ror tmp + 1
ror tmp ror tmp
dex dex
bne L2 bne L2
sta tmp + 2
fas_aligned: fas_aligned:
lda accu + 3 lda accu + 3
@ -1960,8 +1993,8 @@ __asm fmul8
bcc L2 bcc L2
L1: tax L1: tax
clc clc
lda tmp + 6 tya
adc accu adc tmp + 6
sta tmp + 6 sta tmp + 6
lda tmp + 7 lda tmp + 7
adc accu + 1 adc accu + 1
@ -2011,6 +2044,7 @@ W2:
sta tmp + 7 sta tmp + 7
sta tmp + 8 sta tmp + 8
ldy accu
lda tmp lda tmp
jsr fmul8 jsr fmul8
lda tmp + 1 lda tmp + 1
@ -2055,7 +2089,9 @@ W3: and #$7f
__asm inp_binop_mul_f32 __asm inp_binop_mul_f32
{ {
jsr freg.split_exp jsr freg.split_exp
sty tmpy
jsr fmul jsr fmul
ldy tmpy
jmp startup.exec jmp startup.exec
} }

View File

@ -528,6 +528,16 @@ void ByteCodeBasicBlock::FloatConstToAccu(double val)
mIns.Push(bins); mIns.Push(bins);
} }
void ByteCodeBasicBlock::FloatConstToWork(double val)
{
union { float f; int v; } cc;
cc.f = val;
ByteCodeInstruction bins(BC_CONST_32);
bins.mRegister = BC_REG_WORK;
bins.mValue = cc.v;
mIns.Push(bins);
}
void ByteCodeBasicBlock::IntConstToAddr(__int64 val) void ByteCodeBasicBlock::IntConstToAddr(__int64 val)
{ {
@ -622,6 +632,65 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
if (ins.mSType[0] == IT_FLOAT) if (ins.mSType[0] == IT_FLOAT)
{ {
if (ins.mSTemp[1] < 0) if (ins.mSTemp[1] < 0)
{
if (ins.mSTemp[0] < 0)
{
FloatConstToAccu(ins.mSFloatConst[0]);
if (ins.mMemory == IM_GLOBAL)
{
ByteCodeInstruction bins(BC_STORE_ABS_32);
bins.mRelocate = true;
bins.mVIndex = ins.mVarIndex;
bins.mValue = ins.mSIntConst[1];
bins.mRegister = BC_REG_ACCU;
mIns.Push(bins);
}
else if (ins.mMemory == IM_ABSOLUTE)
{
ByteCodeInstruction bins(BC_STORE_ABS_32);
bins.mValue = ins.mSIntConst[1];
bins.mRegister = BC_REG_ACCU;
mIns.Push(bins);
}
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{
int index = ins.mSIntConst[1];
if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset;
else
index += ins.mVarIndex + proc->mLocalSize + 2;
if (index <= 252)
{
ByteCodeInstruction bins(BC_STORE_LOCAL_32);
bins.mRegister = BC_REG_ACCU;
bins.mRegisterFinal = ins.mSFinal[0];
bins.mValue = index;
mIns.Push(bins);
}
else
{
ByteCodeInstruction lins(BC_LEA_LOCAL);
lins.mRegister = BC_REG_ADDR;
lins.mValue = index;
mIns.Push(lins);
ByteCodeInstruction bins(BC_STORE_ADDR_32);
bins.mRegister = BC_REG_ACCU;
bins.mRegisterFinal = ins.mSFinal[0];
mIns.Push(bins);
}
}
else if (ins.mMemory == IM_FRAME)
{
ByteCodeInstruction bins(BC_STORE_FRAME_32);
bins.mRegister = BC_REG_ACCU;
bins.mRegisterFinal = ins.mSFinal[0];
bins.mValue = ins.mVarIndex + ins.mSIntConst[1] + 2;
mIns.Push(bins);
}
}
else
{ {
if (ins.mMemory == IM_GLOBAL) if (ins.mMemory == IM_GLOBAL)
{ {
@ -676,11 +745,12 @@ void ByteCodeBasicBlock::StoreDirectValue(InterCodeProcedure* proc, const InterI
mIns.Push(bins); mIns.Push(bins);
} }
} }
}
else else
{ {
if (ins.mSTemp[0] < 0) if (ins.mSTemp[0] < 0)
{ {
IntConstToAccu(ins.mSIntConst[0]); FloatConstToAccu(ins.mSFloatConst[0]);
if (ins.mMemory == IM_INDIRECT) if (ins.mMemory == IM_INDIRECT)
{ {
@ -1552,13 +1622,31 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
} }
if (ins.mSType[0] == IT_FLOAT) if (ins.mSType[0] == IT_FLOAT)
{
if (ins.mSTemp[0] < 0)
{
FloatConstToAccu(ins.mSFloatConst[0]);
}
else
{ {
ByteCodeInstruction lins(BC_LOAD_REG_32); ByteCodeInstruction lins(BC_LOAD_REG_32);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]; lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]];
lins.mRegisterFinal = ins.mSFinal[0]; lins.mRegisterFinal = ins.mSFinal[0];
mIns.Push(lins); mIns.Push(lins);
}
ByteCodeInstruction cins(BC_BINOP_CMP_F32); ByteCodeInstruction cins(BC_BINOP_CMP_F32);
if (ins.mSTemp[1] < 0)
{
FloatConstToWork(ins.mSFloatConst[1]);
cins.mRegister = BC_REG_WORK;
}
else
{
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]; cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]];
}
cins.mRegisterFinal = ins.mSFinal[1]; cins.mRegisterFinal = ins.mSFinal[1];
mIns.Push(cins); mIns.Push(cins);
} }
@ -1796,16 +1884,30 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns
{ {
ByteCode bc = ByteCodeBinRegOperator(ins); ByteCode bc = ByteCodeBinRegOperator(ins);
if (ins.mSTemp[1] < 0)
{
FloatConstToAccu(ins.mSFloatConst[1]);
}
else
{
ByteCodeInstruction lins(BC_LOAD_REG_32); ByteCodeInstruction lins(BC_LOAD_REG_32);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]; lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]];
lins.mRegisterFinal = ins.mSFinal[1]; lins.mRegisterFinal = ins.mSFinal[1];
mIns.Push(lins); mIns.Push(lins);
}
ByteCodeInstruction bins(bc); ByteCodeInstruction bins(bc);
if (ins.mSTemp[1] == ins.mSTemp[0])
if (ins.mSTemp[0] < 0)
{
FloatConstToWork(ins.mSFloatConst[0]);
bins.mRegister = BC_REG_WORK;
}
else if (ins.mSTemp[1] == ins.mSTemp[0])
bins.mRegister = BC_REG_ACCU; bins.mRegister = BC_REG_ACCU;
else else
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]; bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]];
bins.mRegisterFinal = ins.mSFinal[0]; bins.mRegisterFinal = ins.mSFinal[0];
mIns.Push(bins); mIns.Push(bins);

View File

@ -210,6 +210,7 @@ public:
void IntConstToAccu(__int64 val); void IntConstToAccu(__int64 val);
void IntConstToAddr(__int64 val); void IntConstToAddr(__int64 val);
void FloatConstToAccu(double val); void FloatConstToAccu(double val);
void FloatConstToWork(double val);
void CopyValue(InterCodeProcedure* proc, const InterInstruction& ins); void CopyValue(InterCodeProcedure* proc, const InterInstruction& ins);
void LoadConstant(InterCodeProcedure* proc, const InterInstruction& ins); void LoadConstant(InterCodeProcedure* proc, const InterInstruction& ins);
void StoreDirectValue(InterCodeProcedure* proc, const InterInstruction & ins); void StoreDirectValue(InterCodeProcedure* proc, const InterInstruction & ins);

View File

@ -65,7 +65,7 @@ void Emulator::DumpCycles(void)
} }
printf("Total Cycles %d\n", totalCycles); printf("Total Cycles %d\n", totalCycles);
return; // return;
for (int i = 0; i < numTops; i++) for (int i = 0; i < numTops; i++)
{ {
@ -380,7 +380,7 @@ bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, in
t = (mMemory[addr] >> 1) | ((mRegP & STATUS_CARRY) << 7); t = (mMemory[addr] >> 1) | ((mRegP & STATUS_CARRY) << 7);
mMemory[addr] = t & 255; mMemory[addr] = t & 255;
UpdateStatusCarry(t & 255, c != 0); UpdateStatusCarry(t & 255, c != 0);
cycles++; cycles += 2;
} }
break; break;
case ASMIT_RTI: case ASMIT_RTI:

View File

@ -1633,6 +1633,8 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
switch (ins.mSType[0]) switch (ins.mSType[0])
{ {
case IT_FLOAT: case IT_FLOAT:
ins.mSFloatConst[0] = tvalue[ins.mSTemp[0]]->mFloatValue;
ins.mSTemp[0] = -1;
break; break;
case IT_POINTER: case IT_POINTER:
break; break;
@ -1717,32 +1719,35 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
if (ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT) if (ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT)
{ {
ins.mCode = IC_CONSTANT; ins.mCode = IC_CONSTANT;
ins.mIntValue = ConstantFolding(ins.mOperator, tvalue[ins.mSTemp[1]]->mFloatValue, tvalue[ins.mSTemp[0]]->mFloatValue); ins.mFloatValue = ConstantFolding(ins.mOperator, tvalue[ins.mSTemp[1]]->mFloatValue, tvalue[ins.mSTemp[0]]->mFloatValue);
ins.mSTemp[0] = -1; ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1; ins.mSTemp[1] = -1;
} }
else else
{ {
if (ins.mOperator == IA_ADD && tvalue[ins.mSTemp[1]]->mFloatValue == 0) ins.mSFloatConst[1] = tvalue[ins.mSTemp[1]]->mFloatValue;
ins.mSTemp[1] = -1;
if (ins.mOperator == IA_ADD && ins.mSFloatConst[1] == 0)
{ {
ins.mCode = IC_LOAD_TEMPORARY; ins.mCode = IC_LOAD_TEMPORARY;
assert(ins.mSTemp[0] >= 0); assert(ins.mSTemp[0] >= 0);
} }
else if (ins.mOperator == IA_MUL) else if (ins.mOperator == IA_MUL)
{ {
if (tvalue[ins.mSTemp[1]]->mFloatValue == 1.0) if (ins.mSFloatConst[1] == 1.0)
{ {
ins.mCode = IC_LOAD_TEMPORARY; ins.mCode = IC_LOAD_TEMPORARY;
assert(ins.mSTemp[0] >= 0); assert(ins.mSTemp[0] >= 0);
} }
else if (tvalue[ins.mSTemp[1]]->mFloatValue == 0.0) else if (ins.mSFloatConst[1] == 0.0)
{ {
ins.mCode = IC_CONSTANT; ins.mCode = IC_CONSTANT;
ins.mFloatValue = 0.0; ins.mFloatValue = 0.0;
ins.mSTemp[0] = -1; ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1; ins.mSTemp[1] = -1;
} }
else if (tvalue[ins.mSTemp[1]]->mFloatValue == 2.0) else if (ins.mSFloatConst[1] == 2.0)
{ {
ins.mOperator = IA_ADD; ins.mOperator = IA_ADD;
ins.mSTemp[1] = ins.mSTemp[0]; ins.mSTemp[1] = ins.mSTemp[0];
@ -1753,7 +1758,10 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
} }
else if (ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT) else if (ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT)
{ {
if (ins.mOperator == IA_ADD && tvalue[ins.mSTemp[0]]->mFloatValue == 0) ins.mSFloatConst[0] = tvalue[ins.mSTemp[0]]->mFloatValue;
ins.mSTemp[0] = -1;
if (ins.mOperator == IA_ADD && ins.mSFloatConst[0] == 0)
{ {
ins.mCode = IC_LOAD_TEMPORARY; ins.mCode = IC_LOAD_TEMPORARY;
ins.mSTemp[0] = ins.mSTemp[1]; ins.mSTemp[0] = ins.mSTemp[1];
@ -1762,21 +1770,21 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
} }
else if (ins.mOperator == IA_MUL) else if (ins.mOperator == IA_MUL)
{ {
if (tvalue[ins.mSTemp[0]]->mFloatValue == 1.0) if (ins.mSFloatConst[0] == 1.0)
{ {
ins.mCode = IC_LOAD_TEMPORARY; ins.mCode = IC_LOAD_TEMPORARY;
ins.mSTemp[0] = ins.mSTemp[1]; ins.mSTemp[0] = ins.mSTemp[1];
ins.mSTemp[1] = -1; ins.mSTemp[1] = -1;
assert(ins.mSTemp[0] >= 0); assert(ins.mSTemp[0] >= 0);
} }
else if (tvalue[ins.mSTemp[0]]->mFloatValue == 0.0) else if (ins.mSFloatConst[0] == 0.0)
{ {
ins.mCode = IC_CONSTANT; ins.mCode = IC_CONSTANT;
ins.mFloatValue = 0.0; ins.mFloatValue = 0.0;
ins.mSTemp[0] = -1; ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1; ins.mSTemp[1] = -1;
} }
else if (tvalue[ins.mSTemp[0]]->mFloatValue == 2.0) else if (ins.mSFloatConst[0] == 2.0)
{ {
ins.mOperator = IA_ADD; ins.mOperator = IA_ADD;
ins.mSTemp[0] = ins.mSTemp[1]; ins.mSTemp[0] = ins.mSTemp[1];
@ -1847,7 +1855,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
{ {
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue; ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
ins.mSTemp[0] = -1; ins.mSTemp[0] = -1;
#if 1
if (ins.mOperator == IA_ADD && ins.mSIntConst[0] == 0) if (ins.mOperator == IA_ADD && ins.mSIntConst[0] == 0)
{ {
ins.mCode = IC_LOAD_TEMPORARY; ins.mCode = IC_LOAD_TEMPORARY;
@ -1880,7 +1888,6 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
ins.mSIntConst[0] = 3; ins.mSIntConst[0] = 3;
} }
} }
#endif
} }
if (ins.mSTemp[1] < 0 && ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_BINARY_OPERATOR) if (ins.mSTemp[1] < 0 && ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_BINARY_OPERATOR)
@ -1948,6 +1955,28 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
switch (ins.mSType[1]) switch (ins.mSType[1])
{ {
case IT_FLOAT: case IT_FLOAT:
if (ins.mSTemp[1] >= 0 && tvalue[ins.mSTemp[1]] && tvalue[ins.mSTemp[1]]->mCode == IC_CONSTANT &&
ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT)
{
ins.mCode = IC_CONSTANT;
ins.mIntValue = ConstantRelationalFolding(ins.mOperator, tvalue[ins.mSTemp[1]]->mFloatValue, tvalue[ins.mSTemp[0]]->mFloatValue);
ins.mTType = IT_SIGNED;
ins.mSTemp[0] = -1;
ins.mSTemp[1] = -1;
}
else
{
if (ins.mSTemp[1] >= 0 && tvalue[ins.mSTemp[1]] && tvalue[ins.mSTemp[1]]->mCode == IC_CONSTANT)
{
ins.mSFloatConst[1] = tvalue[ins.mSTemp[1]]->mFloatValue;
ins.mSTemp[1] = -1;
}
else if (ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT)
{
ins.mSFloatConst[0] = tvalue[ins.mSTemp[0]]->mFloatValue;
ins.mSTemp[0] = -1;
}
}
break; break;
case IT_POINTER: case IT_POINTER:
if (ins.mOperator == IA_CMPEQ || ins.mOperator == IA_CMPNE) if (ins.mOperator == IA_CMPEQ || ins.mOperator == IA_CMPNE)
@ -2634,6 +2663,62 @@ bool InterCodeBasicBlock::IsLeafProcedure(void)
return true; return true;
} }
static bool CanBypassLoad(const InterInstruction& lins, const InterInstruction& bins)
{
// Check ambiguity
if (bins.mCode == IC_STORE || bins.mCode == IC_COPY)
return false;
// Side effects
if (bins.mCode == IC_CALL || bins.mCode == IC_JSR)
return false;
// True data dependency
if (lins.mTTemp == bins.mSTemp[0] || lins.mTTemp == bins.mSTemp[1] || lins.mTTemp == bins.mSTemp[2])
return false;
// False data dependency
if (lins.mSTemp[0] >= 0 && lins.mSTemp[0] == bins.mTTemp)
return false;
return true;
}
static bool CanBypassStore(const InterInstruction& sins, const InterInstruction& bins)
{
if (bins.mCode == IC_COPY || bins.mCode == IC_PUSH_FRAME)
return false;
// Check ambiguity
if (bins.mCode == IC_STORE || bins.mCode == IC_LOAD)
{
if (sins.mMemory == IM_LOCAL)
{
if (bins.mMemory == IM_PARAM || bins.mMemory == IM_GLOBAL)
;
else if (bins.mMemory == IM_LOCAL)
{
if (bins.mVarIndex == sins.mVarIndex)
return false;
}
else
return false;
}
else
return false;
}
// Side effects
if (bins.mCode == IC_CALL || bins.mCode == IC_JSR)
return false;
// True data dependency
if (bins.mTTemp >= 0 && (bins.mTTemp == sins.mSTemp[0] || bins.mTTemp == sins.mSTemp[1]))
return false;
return true;
}
void InterCodeBasicBlock::PeepholeOptimization(void) void InterCodeBasicBlock::PeepholeOptimization(void)
{ {
int i; int i;
@ -2642,6 +2727,49 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
{ {
mVisited = true; mVisited = true;
// shorten lifespan
int i = mInstructions.Size() - 2;
while (i >= 0)
{
// move loads down
if (mInstructions[i].mCode == IC_LOAD)
{
InterInstruction ins(mInstructions[i]);
int j = i;
while (j + 2 < mInstructions.Size() && CanBypassLoad(ins, mInstructions[j + 1]))
{
mInstructions[j] = mInstructions[j + 1];
j++;
}
if (i != j)
mInstructions[j] = ins;
}
i--;
}
i = 0;
while (i < mInstructions.Size())
{
// move stores up
if (mInstructions[i].mCode == IC_STORE)
{
InterInstruction ins(mInstructions[i]);
int j = i;
while (j > 0 && CanBypassStore(ins, mInstructions[j - 1]))
{
mInstructions[j] = mInstructions[j - 1];
j--;
}
if (i != j)
mInstructions[j] = ins;
}
i++;
}
bool changed; bool changed;
do do
{ {
@ -2681,6 +2809,29 @@ void InterCodeBasicBlock::PeepholeOptimization(void)
mInstructions[i + 2].mSFinal[1] = false; mInstructions[i + 2].mSFinal[1] = false;
changed = true; changed = true;
} }
else if (
mInstructions[i + 0].mCode == IC_BINARY_OPERATOR && mInstructions[i + 0].mOperator == IA_SAR && mInstructions[i + 0].mSTemp[0] < 0 &&
mInstructions[i + 1].mCode == IC_BINARY_OPERATOR && mInstructions[i + 1].mOperator == IA_MUL && mInstructions[i + 1].mSTemp[0] < 0 &&
mInstructions[i + 1].mSTemp[1] == mInstructions[i + 0].mTTemp && mInstructions[i + 1].mSFinal[1] &&
(mInstructions[i + 1].mSIntConst[0] & (1LL << mInstructions[i + 0].mSIntConst[0])) == 0)
{
int shift = mInstructions[i + 0].mSIntConst[0];
mInstructions[i + 1].mSIntConst[0] >>= shift;
mInstructions[i + 0].mOperator = IA_AND;
mInstructions[i + 0].mSIntConst[0] = ~((1LL << shift) - 1);
}
else if (
mInstructions[i + 0].mCode == IC_BINARY_OPERATOR && mInstructions[i + 0].mOperator == IA_SAR && mInstructions[i + 0].mSTemp[0] < 0 &&
mInstructions[i + 1].mCode == IC_BINARY_OPERATOR && mInstructions[i + 1].mOperator == IA_MUL && mInstructions[i + 1].mSTemp[1] < 0 &&
mInstructions[i + 1].mSTemp[0] == mInstructions[i + 0].mTTemp && mInstructions[i + 1].mSFinal[0] &&
(mInstructions[i + 1].mSIntConst[1] & (1LL << mInstructions[i + 0].mSIntConst[0])) == 0)
{
int shift = mInstructions[i + 0].mSIntConst[0];
mInstructions[i + 1].mSIntConst[1] >>= shift;
mInstructions[i + 0].mOperator = IA_AND;
mInstructions[i + 0].mSIntConst[0] = ~((1LL << shift) - 1);
}
// 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 &&

View File

@ -264,6 +264,7 @@ public:
int mTTemp, mSTemp[3]; int mTTemp, mSTemp[3];
bool mSFinal[3]; bool mSFinal[3];
__int64 mSIntConst[3]; __int64 mSIntConst[3];
double mSFloatConst[3];
InterMemory mMemory; InterMemory mMemory;
InterOperator mOperator; InterOperator mOperator;
int mOperandSize; int mOperandSize;

View File

@ -214,11 +214,14 @@ void NativeCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterIns
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
if (index != 0)
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
if (index != 0)
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, (mNoFrame ? BC_REG_STACK : BC_REG_LOCALS) + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, (mNoFrame ? BC_REG_STACK : BC_REG_LOCALS) + 1));
if (index != 0)
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
} }
@ -244,26 +247,29 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
{ {
if (ins.mSTemp[0] < 0) if (ins.mSTemp[0] < 0)
{ {
union { float f; unsigned int v; } cc;
cc.f = ins.mSFloatConst[0];
if (ins.mMemory == IM_GLOBAL) if (ins.mMemory == IM_GLOBAL)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1], ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1], ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1, ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 16) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2, ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 24) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3, ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3, ins.mVarIndex));
} }
else if (ins.mMemory == IM_ABSOLUTE) else if (ins.mMemory == IM_ABSOLUTE)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 16) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 24) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3));
} }
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
@ -275,16 +281,16 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 16) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 24) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
@ -293,26 +299,35 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
} }
else else
{ {
int sreg = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]];
if (ins.mSFinal[0] && CheckPredAccuStore(sreg))
{
// cull previous store from accu to temp using direcrt forwarding from accu
mIns.SetSize(mIns.Size() - 8);
sreg = BC_REG_ACCU;
}
if (ins.mMemory == IM_GLOBAL) if (ins.mMemory == IM_GLOBAL)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1], ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1], ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1, ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2, ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3, ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3, ins.mVarIndex));
} }
else if (ins.mMemory == IM_ABSOLUTE) else if (ins.mMemory == IM_ABSOLUTE)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3));
} }
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
@ -324,16 +339,16 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
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.mSTemp[0]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
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.mSTemp[0]] + 2)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
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.mSTemp[0]] + 3)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
@ -995,6 +1010,26 @@ void NativeCodeBasicBlock::LoadValue(InterCodeProcedure* proc, const InterInstru
LoadValueToReg(proc, ins, BC_REG_TMP + proc->mTempOffset[ins.mTTemp], nullptr, nullptr); LoadValueToReg(proc, ins, BC_REG_TMP + proc->mTempOffset[ins.mTTemp], nullptr, nullptr);
} }
bool NativeCodeBasicBlock::CheckPredAccuStore(int reg)
{
if (mIns.Size() < 8)
return false;
int p = mIns.Size() - 8;
for (int i = 0; i < 4; i++)
{
if (mIns[p + 0].mType != ASMIT_LDA || mIns[p + 0].mMode != ASMIM_ZERO_PAGE || mIns[p + 0].mAddress != BC_REG_ACCU + i)
return false;
if (mIns[p + 1].mType != ASMIT_STA || mIns[p + 1].mMode != ASMIM_ZERO_PAGE || mIns[p + 1].mAddress != reg + i)
return false;
p += 2;
}
return true;
}
void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterInstruction& ins, const InterInstruction * sins1, const InterInstruction * sins0) void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterInstruction& ins, const InterInstruction * sins1, const InterInstruction * sins0)
{ {
int treg = BC_REG_TMP + proc->mTempOffset[ins.mTTemp]; int treg = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
@ -1003,15 +1038,27 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
{ {
if (ins.mSTemp[1] < 0) if (ins.mSTemp[1] < 0)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[1] & 0xff)); union { float f; unsigned int v; } cc;
cc.f = ins.mSFloatConst[1];
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[1] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[1] >> 16) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[1] >> 24) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
} }
else if (sins1)
{
LoadValueToReg(proc, *sins1, BC_REG_ACCU, nullptr, nullptr);
}
else if (ins.mSFinal[1] && CheckPredAccuStore(BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]))
{
// cull previous store from accu to temp using direcrt forwarding
mIns.SetSize(mIns.Size() - 8);
}
else else
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]] + 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]] + 0));
@ -1026,15 +1073,22 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
if (ins.mSTemp[0] < 0) if (ins.mSTemp[0] < 0)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff)); union { float f; unsigned int v; } cc;
cc.f = ins.mSFloatConst[0];
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 16) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 24) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
} }
else if (sins0)
{
LoadValueToReg(proc, *sins0, BC_REG_WORK, nullptr, nullptr);
}
else else
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 0));
@ -1264,6 +1318,46 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
case IA_MODS: case IA_MODS:
case IA_DIVU: case IA_DIVU:
case IA_MODU: case IA_MODU:
{
int reg = BC_REG_ACCU;
if (ins.mOperator == IA_MUL && ins.mSTemp[1] < 0 && (ins.mSIntConst[1] & ~0xff) == 0)
{
if (sins0)
LoadValueToReg(proc, *sins0, BC_REG_ACCU, nullptr, nullptr);
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
}
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[1] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction("mul16by8"));
reg = BC_REG_WORK + 2;
}
else if (ins.mOperator == IA_MUL && ins.mSTemp[0] < 0 && (ins.mSIntConst[0] & ~0xff) == 0)
{
if (sins1)
LoadValueToReg(proc, *sins1, BC_REG_ACCU, nullptr, nullptr);
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
}
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction("mul16by8"));
reg = BC_REG_WORK + 2;
}
else
{ {
if (sins1) if (sins1)
LoadValueToReg(proc, *sins1, BC_REG_ACCU, nullptr, nullptr); LoadValueToReg(proc, *sins1, BC_REG_ACCU, nullptr, nullptr);
@ -1299,7 +1393,6 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1));
} }
int reg = BC_REG_ACCU;
switch (ins.mOperator) switch (ins.mOperator)
{ {
case IA_MUL: case IA_MUL:
@ -1321,6 +1414,7 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
reg = BC_REG_WORK + 2; reg = BC_REG_WORK + 2;
break; break;
} }
}
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp]));
@ -1629,15 +1723,23 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
if (ins.mSTemp[li] < 0) if (ins.mSTemp[li] < 0)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[li] & 0xff)); union { float f; unsigned int v; } cc;
cc.f = ins.mSFloatConst[li];
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[li] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[li] >> 16) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[li] >> 24) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
} }
else if (ins.mSFinal[li] && CheckPredAccuStore(BC_REG_TMP + proc->mTempOffset[ins.mSTemp[li]]))
{
// cull previous store from accu to temp using direcrt forwarding
mIns.SetSize(mIns.Size() - 8);
}
else else
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[li]] + 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[li]] + 0));
@ -1652,13 +1754,16 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
if (ins.mSTemp[ri] < 0) if (ins.mSTemp[ri] < 0)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[ri] & 0xff)); union { float f; unsigned int v; } cc;
cc.f = ins.mSFloatConst[ri];
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[ri] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[ri] >> 16) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[ri] >> 24) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
} }
else else
@ -1747,7 +1852,7 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[ri]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[ri]] + 1));
} }
this->Close(eblock, nblock, ASMIT_BEQ); this->Close(nblock, eblock, ASMIT_BNE);
if (ins.mSTemp[li] < 0) if (ins.mSTemp[li] < 0)
eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[li] & 0xff)); eblock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[li] & 0xff));
@ -1789,34 +1894,120 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins) void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins)
{ {
if (ins.mSTemp[0] >= 0 || ins.mSIntConst[0] != 0)
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
if (ins.mSTemp[1] < 0) if (ins.mSTemp[1] < 0)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[1] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[1] & 0xff));
else else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
if (ins.mSTemp[0] < 0) if (ins.mSTemp[0] < 0)
{
if (ins.mSIntConst[0])
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
}
else else
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp]));
if (ins.mSTemp[1] < 0) if (ins.mSTemp[1] < 0)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[1] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[1] >> 8) & 0xff));
else else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]] + 1));
if (ins.mSTemp[0] < 0) if (ins.mSTemp[0] < 0)
{
if (ins.mSIntConst[0])
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff));
}
else else
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
} }
void NativeCodeBasicBlock::PeepHoleOptimizer(void)
{
bool progress = false;
do {
progress = false;
int i = 0;
int j = 0;
while (i < mIns.Size())
{
if (mIns[i].mType == ASMIT_NOP)
;
else
{
if (i != j)
mIns[j] = mIns[i];
j++;
}
i++;
}
mIns.SetSize(j);
for (int i = 0; i < mIns.Size(); i++)
{
if (mIns[i].mType == ASMIT_AND && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0)
{
mIns[i].mType = ASMIT_LDA;
progress = true;
}
else if (mIns[i].mType == ASMIT_AND && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0xff)
{
mIns[i].mType = ASMIT_NOP;
progress = true;
}
else if (mIns[i].mType == ASMIT_ORA && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0xff)
{
mIns[i].mType = ASMIT_LDA;
progress = true;
}
else if (mIns[i].mType == ASMIT_ORA && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0x00)
{
mIns[i].mType = ASMIT_NOP;
progress = true;
}
if (i + 1 < mIns.Size())
{
if (mIns[i].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_LDA)
{
mIns[i].mType = ASMIT_NOP;
progress = true;
}
else if (mIns[i].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_STA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress)
{
mIns[i + 1].mType = ASMIT_NOP;
progress = true;
}
}
if (i + 2 < mIns.Size())
{
if (mIns[i].mType == ASMIT_LDA && mIns[i + 2].mType == ASMIT_LDA && (mIns[i + 1].mType == ASMIT_CLC || mIns[i + 1].mType == ASMIT_SEC))
{
mIns[i].mType = ASMIT_NOP;
progress = true;
}
}
}
} while (progress);
}
void NativeCodeBasicBlock::Assemble(void) void NativeCodeBasicBlock::Assemble(void)
{ {
if (!mAssembled) if (!mAssembled)
{ {
mAssembled = true; mAssembled = true;
//PeepHoleOptimizer(); PeepHoleOptimizer();
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
mIns[i].Assemble(this); mIns[i].Assemble(this);
@ -2240,7 +2431,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
i++; i++;
} }
else if (i + 1 < iblock->mInstructions.Size() && else if (i + 1 < iblock->mInstructions.Size() &&
ins.mOperandSize == 2 && ins.mOperandSize >= 2 &&
iblock->mInstructions[i + 1].mCode == IC_BINARY_OPERATOR && iblock->mInstructions[i + 1].mCode == IC_BINARY_OPERATOR &&
iblock->mInstructions[i + 1].mSTemp[0] == ins.mTTemp && iblock->mInstructions[i + 1].mSFinal[0]) iblock->mInstructions[i + 1].mSTemp[0] == ins.mTTemp && iblock->mInstructions[i + 1].mSFinal[0])
{ {
@ -2248,7 +2439,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
i++; i++;
} }
else if (i + 1 < iblock->mInstructions.Size() && else if (i + 1 < iblock->mInstructions.Size() &&
ins.mOperandSize == 2 && ins.mOperandSize >= 2 &&
iblock->mInstructions[i + 1].mCode == IC_BINARY_OPERATOR && iblock->mInstructions[i + 1].mCode == IC_BINARY_OPERATOR &&
iblock->mInstructions[i + 1].mSTemp[1] == ins.mTTemp && iblock->mInstructions[i + 1].mSFinal[1]) iblock->mInstructions[i + 1].mSTemp[1] == ins.mTTemp && iblock->mInstructions[i + 1].mSFinal[1])
{ {
@ -2256,7 +2447,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
i++; i++;
} }
else if (i + 2 < iblock->mInstructions.Size() && else if (i + 2 < iblock->mInstructions.Size() &&
ins.mOperandSize == 2 && ins.mOperandSize >= 2 &&
iblock->mInstructions[i + 1].mCode == IC_LOAD && iblock->mInstructions[i + 1].mOperandSize == 2 && iblock->mInstructions[i + 1].mCode == IC_LOAD && iblock->mInstructions[i + 1].mOperandSize == 2 &&
iblock->mInstructions[i + 2].mCode == IC_BINARY_OPERATOR && iblock->mInstructions[i + 2].mCode == IC_BINARY_OPERATOR &&
iblock->mInstructions[i + 2].mSTemp[0] == iblock->mInstructions[i + 1].mTTemp && iblock->mInstructions[i + 2].mSFinal[0] && iblock->mInstructions[i + 2].mSTemp[0] == iblock->mInstructions[i + 1].mTTemp && iblock->mInstructions[i + 2].mSFinal[0] &&
@ -2266,7 +2457,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
i += 2; i += 2;
} }
else if (i + 2 < iblock->mInstructions.Size() && else if (i + 2 < iblock->mInstructions.Size() &&
ins.mOperandSize == 2 && ins.mOperandSize >= 2 &&
iblock->mInstructions[i + 1].mCode == IC_LOAD && iblock->mInstructions[i + 1].mOperandSize == 2 && iblock->mInstructions[i + 1].mCode == IC_LOAD && iblock->mInstructions[i + 1].mOperandSize == 2 &&
iblock->mInstructions[i + 2].mCode == IC_BINARY_OPERATOR && iblock->mInstructions[i + 2].mCode == IC_BINARY_OPERATOR &&
iblock->mInstructions[i + 2].mSTemp[1] == iblock->mInstructions[i + 1].mTTemp && iblock->mInstructions[i + 2].mSFinal[1] && iblock->mInstructions[i + 2].mSTemp[1] == iblock->mInstructions[i + 1].mTTemp && iblock->mInstructions[i + 2].mSFinal[1] &&

View File

@ -50,6 +50,8 @@ public:
void Assemble(void); void Assemble(void);
void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch); void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
void PeepHoleOptimizer(void);
void PutByte(uint8 code); void PutByte(uint8 code);
void PutWord(uint16 code); void PutWord(uint16 code);
@ -64,6 +66,8 @@ public:
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump); void RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins); void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins);
void NumericConversion(InterCodeProcedure* proc, const InterInstruction& ins); void NumericConversion(InterCodeProcedure* proc, const InterInstruction& ins);
bool CheckPredAccuStore(int reg);
}; };
class NativeCodeProcedure class NativeCodeProcedure