Optimize long divide for short divisor
This commit is contained in:
parent
4a9c662cc9
commit
893b6f2294
|
@ -24,5 +24,16 @@ int main(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(unsigned i=0; i<64000; i+=121)
|
||||||
|
{
|
||||||
|
for(unsigned j=1; j<i; j*=3)
|
||||||
|
{
|
||||||
|
unsigned q = i / j, r = i % j;
|
||||||
|
|
||||||
|
assert(q * j + r == i);
|
||||||
|
assert(r >= 0 && r < j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -379,12 +379,46 @@ W1: dey
|
||||||
__asm divmod32
|
__asm divmod32
|
||||||
{
|
{
|
||||||
sty tmpy
|
sty tmpy
|
||||||
|
ldy #32
|
||||||
|
|
||||||
lda #0
|
lda #0
|
||||||
sta tmp + 4
|
sta tmp + 4
|
||||||
sta tmp + 5
|
sta tmp + 5
|
||||||
sta tmp + 6
|
sta tmp + 6
|
||||||
sta tmp + 7
|
sta tmp + 7
|
||||||
ldy #32
|
|
||||||
|
lda tmp + 2
|
||||||
|
ora tmp + 3
|
||||||
|
bne W32
|
||||||
|
|
||||||
|
// divide 32 by 16 bit
|
||||||
|
|
||||||
|
clc
|
||||||
|
LS1: rol accu
|
||||||
|
rol accu + 1
|
||||||
|
rol accu + 2
|
||||||
|
rol accu + 3
|
||||||
|
rol tmp + 4
|
||||||
|
rol tmp + 5
|
||||||
|
sec
|
||||||
|
lda tmp + 4
|
||||||
|
sbc tmp
|
||||||
|
tax
|
||||||
|
lda tmp + 5
|
||||||
|
sbc tmp + 1
|
||||||
|
bcc WS1
|
||||||
|
stx tmp + 4
|
||||||
|
sta tmp + 5
|
||||||
|
WS1: dey
|
||||||
|
bne LS1
|
||||||
|
rol accu
|
||||||
|
rol accu + 1
|
||||||
|
rol accu + 2
|
||||||
|
rol accu + 3
|
||||||
|
ldy tmpy
|
||||||
|
rts
|
||||||
|
|
||||||
|
W32:
|
||||||
clc
|
clc
|
||||||
L1: rol accu
|
L1: rol accu
|
||||||
rol accu + 1
|
rol accu + 1
|
||||||
|
|
|
@ -9286,26 +9286,57 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo
|
||||||
|
|
||||||
void NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* lblock)
|
void NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc, NativeCodeBasicBlock* lblock)
|
||||||
{
|
{
|
||||||
if (lblock->mIns[0].mType == ASMIT_LDA && lblock->mIns[0].mMode == ASMIM_IMMEDIATE)
|
int ai = 0;
|
||||||
|
while (ai < lblock->mIns.Size() && !lblock->mIns[ai].ChangesAccu())
|
||||||
|
ai++;
|
||||||
|
|
||||||
|
if (lblock->mIns[ai].mType == ASMIT_LDA && lblock->mIns[ai].mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
int i = 1;
|
int i = ai + 1;
|
||||||
while (i < lblock->mIns.Size() && !lblock->mIns[i].ChangesAccu())
|
while (i < lblock->mIns.Size() && !lblock->mIns[i].ChangesAccu())
|
||||||
i++;
|
i++;
|
||||||
if (i == lblock->mIns.Size())
|
if (i == lblock->mIns.Size())
|
||||||
{
|
{
|
||||||
mIns.Push(lblock->mIns[0]);
|
mIns.Push(lblock->mIns[ai]);
|
||||||
lblock->mIns.Remove(0);
|
lblock->mIns.Remove(ai);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lblock->mIns[0].mType == ASMIT_LDA && lblock->mIns[0].mMode == ASMIM_ZERO_PAGE)
|
else if (lblock->mIns[ai].mType == ASMIT_LDA && lblock->mIns[ai].mMode == ASMIM_ZERO_PAGE)
|
||||||
{
|
{
|
||||||
int i = 1;
|
int i = ai + 1;
|
||||||
while (i < lblock->mIns.Size() && !lblock->mIns[i].ChangesAccu() && !lblock->mIns[i].ChangesZeroPage(lblock->mIns[0].mAddress))
|
while (i < lblock->mIns.Size() && !lblock->mIns[i].ChangesAccu() && !lblock->mIns[i].ChangesZeroPage(lblock->mIns[0].mAddress))
|
||||||
i++;
|
i++;
|
||||||
if (i == lblock->mIns.Size())
|
if (i == lblock->mIns.Size())
|
||||||
{
|
{
|
||||||
mIns.Push(lblock->mIns[0]);
|
mIns.Push(lblock->mIns[ai]);
|
||||||
lblock->mIns.Remove(0);
|
lblock->mIns.Remove(ai);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ai = 0;
|
||||||
|
while (ai < lblock->mIns.Size() && !lblock->mIns[ai].ChangesYReg())
|
||||||
|
ai++;
|
||||||
|
|
||||||
|
if (lblock->mIns[ai].mType == ASMIT_LDY && lblock->mIns[ai].mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
int i = ai + 1;
|
||||||
|
while (i < lblock->mIns.Size() && !lblock->mIns[i].ChangesYReg())
|
||||||
|
i++;
|
||||||
|
if (i == lblock->mIns.Size())
|
||||||
|
{
|
||||||
|
mIns.Push(lblock->mIns[ai]);
|
||||||
|
lblock->mIns.Remove(ai);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (lblock->mIns[ai].mType == ASMIT_LDY && lblock->mIns[ai].mMode == ASMIM_ZERO_PAGE)
|
||||||
|
{
|
||||||
|
int i = ai + 1;
|
||||||
|
while (i < lblock->mIns.Size() && !lblock->mIns[i].ChangesYReg() && !lblock->mIns[i].ChangesZeroPage(lblock->mIns[0].mAddress))
|
||||||
|
i++;
|
||||||
|
if (i == lblock->mIns.Size())
|
||||||
|
{
|
||||||
|
mIns.Push(lblock->mIns[ai]);
|
||||||
|
lblock->mIns.Remove(ai);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10426,6 +10457,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
NativeCodeInstruction pins = mIns[i];
|
NativeCodeInstruction pins = mIns[i];
|
||||||
mIns[i] = mIns[i + 1];
|
mIns[i] = mIns[i + 1];
|
||||||
mIns[i + 1] = pins;
|
mIns[i + 1] = pins;
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10444,7 +10476,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
while (j < mIns.Size() && !mIns[j].ChangesXReg() && !mIns[j].ChangesYReg())
|
while (j < mIns.Size() && !mIns[j].ChangesXReg() && !mIns[j].ChangesYReg())
|
||||||
{
|
{
|
||||||
if (mIns[j].mMode == ASMIM_ABSOLUTE_Y)
|
if (mIns[j].mMode == ASMIM_ABSOLUTE_Y)
|
||||||
|
{
|
||||||
mIns[j].mMode = ASMIM_ABSOLUTE_X;
|
mIns[j].mMode = ASMIM_ABSOLUTE_X;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10454,7 +10489,10 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
while (j < mIns.Size() && !mIns[j].ChangesXReg() && !mIns[j].ChangesYReg())
|
while (j < mIns.Size() && !mIns[j].ChangesXReg() && !mIns[j].ChangesYReg())
|
||||||
{
|
{
|
||||||
if (mIns[j].mMode == ASMIM_ABSOLUTE_X)
|
if (mIns[j].mMode == ASMIM_ABSOLUTE_X)
|
||||||
|
{
|
||||||
mIns[j].mMode = ASMIM_ABSOLUTE_Y;
|
mIns[j].mMode = ASMIM_ABSOLUTE_Y;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10501,7 +10539,8 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
|
|
||||||
mIns.Reserve(mIns.Size() * 2 + 32);
|
mIns.Reserve(mIns.Size() * 2 + 32);
|
||||||
|
|
||||||
changed = RemoveNops();
|
if (RemoveNops())
|
||||||
|
changed = true;
|
||||||
|
|
||||||
// Replace (a & 0x80) != 0 with bpl/bmi
|
// Replace (a & 0x80) != 0 with bpl/bmi
|
||||||
int sz = mIns.Size();
|
int sz = mIns.Size();
|
||||||
|
@ -10833,6 +10872,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
#if 1
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TXA &&
|
mIns[i + 0].mType == ASMIT_TXA &&
|
||||||
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
||||||
|
@ -10840,6 +10880,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
|
||||||
mIns[i + 1].mType = ASMIT_STX;
|
mIns[i + 1].mType = ASMIT_STX;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 0].mType == ASMIT_TYA &&
|
mIns[i + 0].mType == ASMIT_TYA &&
|
||||||
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
mIns[i + 1].mType == ASMIT_STA && (mIns[i + 1].mMode == ASMIM_ZERO_PAGE || mIns[i + 1].mMode == ASMIM_ABSOLUTE))
|
||||||
|
|
|
@ -563,7 +563,7 @@ Declaration * Parser::CopyConstantInitializer(int offset, Declaration* dtype, Ex
|
||||||
dec->mOffset = offset;
|
dec->mOffset = offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dtype->mType == DT_TYPE_POINTER && dec->mType == DT_VARIABLE && dec->mBase->mType == DT_TYPE_ARRAY && (dec->mFlags & DTF_STATIC))
|
else if (dtype->mType == DT_TYPE_POINTER && dec->mType == DT_VARIABLE && dec->mBase->mType == DT_TYPE_ARRAY && (dec->mFlags & DTF_GLOBAL))
|
||||||
{
|
{
|
||||||
if (dtype->CanAssign(exp->mDecType))
|
if (dtype->CanAssign(exp->mDecType))
|
||||||
{
|
{
|
||||||
|
@ -3126,7 +3126,7 @@ void Parser::ParsePragma(void)
|
||||||
if (mScanner->mToken == TK_IDENT)
|
if (mScanner->mToken == TK_IDENT)
|
||||||
{
|
{
|
||||||
Declaration* dec = mGlobals->Lookup(mScanner->mTokenIdent);
|
Declaration* dec = mGlobals->Lookup(mScanner->mTokenIdent);
|
||||||
if (dec && dec->mType == DT_VARIABLE && (dec->mFlags & DTF_STATIC))
|
if (dec && dec->mType == DT_VARIABLE && (dec->mFlags & DTF_GLOBAL))
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
ConsumeToken(TK_COMMA);
|
ConsumeToken(TK_COMMA);
|
||||||
|
|
Loading…
Reference in New Issue