More simple loop optimisations
This commit is contained in:
parent
e72d28c243
commit
c4a5dafb69
|
@ -0,0 +1,48 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int asum(int a, int b)
|
||||||
|
{
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
ldy #a
|
||||||
|
clc
|
||||||
|
lda (fp), y
|
||||||
|
ldy #b
|
||||||
|
adc (fp), y
|
||||||
|
sta accu
|
||||||
|
ldy #a + 1
|
||||||
|
lda (fp), y
|
||||||
|
ldy #b + 1
|
||||||
|
adc (fp), y
|
||||||
|
sta accu + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsum(int a, int b)
|
||||||
|
{
|
||||||
|
printf("Hello\n");
|
||||||
|
|
||||||
|
__asm
|
||||||
|
{
|
||||||
|
ldy #a
|
||||||
|
clc
|
||||||
|
lda (fp), y
|
||||||
|
ldy #b
|
||||||
|
adc (fp), y
|
||||||
|
sta accu
|
||||||
|
ldy #a + 1
|
||||||
|
lda (fp), y
|
||||||
|
ldy #b + 1
|
||||||
|
adc (fp), y
|
||||||
|
sta accu + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int x = asum(7007, 8008);
|
||||||
|
int y = bsum(4004, 9009);
|
||||||
|
|
||||||
|
return (x == 7007 + 8008 && y == 4004 + 9009) ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
|
@ -102,6 +102,12 @@ if %errorlevel% neq 0 goto :error
|
||||||
..\release\oscar64 -e -n byteindextest.c
|
..\release\oscar64 -e -n byteindextest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
..\release\oscar64 -e asmtest.c
|
||||||
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
..\release\oscar64 -e -n asmtest.c
|
||||||
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
exit /b 0
|
exit /b 0
|
||||||
:error
|
:error
|
||||||
echo Failed with error #%errorlevel%.
|
echo Failed with error #%errorlevel%.
|
||||||
|
|
|
@ -983,6 +983,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
cins->mTTemp = proc->AddTemporary(cins->mTType);
|
cins->mTTemp = proc->AddTemporary(cins->mTType);
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
|
||||||
|
vr = CoerceType(proc, block, vr, TheSignedIntTypeDeclaration);
|
||||||
|
|
||||||
InterInstruction * mins = new InterInstruction();
|
InterInstruction * mins = new InterInstruction();
|
||||||
mins->mCode = IC_BINARY_OPERATOR;
|
mins->mCode = IC_BINARY_OPERATOR;
|
||||||
mins->mOperator = IA_MUL;
|
mins->mOperator = IA_MUL;
|
||||||
|
|
|
@ -444,6 +444,21 @@ bool NativeCodeInstruction::ChangesAccuAndFlag(void) const
|
||||||
mType == ASMIT_SBC || mType == ASMIT_ADC;
|
mType == ASMIT_SBC || mType == ASMIT_ADC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NativeCodeInstruction::RequiresYReg(void) const
|
||||||
|
{
|
||||||
|
if (mMode == ASMIM_ABSOLUTE_Y || mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_ZERO_PAGE_Y)
|
||||||
|
return true;
|
||||||
|
if (mType == ASMIT_TYA || mType == ASMIT_STY || mType == ASMIT_CPY || mType == ASMIT_INY || mType == ASMIT_DEY)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeInstruction::ChangesYReg(void) const
|
||||||
|
{
|
||||||
|
return mType == ASMIT_TAY || mType == ASMIT_LDY || mType == ASMIT_INY || mType == ASMIT_DEY;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeInstruction::RequiresAccu(void) const
|
bool NativeCodeInstruction::RequiresAccu(void) const
|
||||||
{
|
{
|
||||||
if (mMode == ASMIM_IMPLIED)
|
if (mMode == ASMIM_IMPLIED)
|
||||||
|
@ -5138,9 +5153,18 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
mVisited = true;
|
mVisited = true;
|
||||||
|
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
|
||||||
int sz = mIns.Size();
|
int sz = mIns.Size();
|
||||||
if (sz > 3 && sz < 16 && mNumEntries == 2 && mTrueJump == this)
|
if (sz > 3 && sz < 32 && mNumEntries == 2 && mTrueJump == this)
|
||||||
|
{
|
||||||
|
bool simple = true;
|
||||||
|
|
||||||
|
for(int i=0; i<mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_JSR)
|
||||||
|
simple = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simple)
|
||||||
{
|
{
|
||||||
if (mIns[sz - 3].mType == ASMIT_INC && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
|
if (mIns[sz - 3].mType == ASMIT_INC && mIns[sz - 3].mMode == ASMIM_ZERO_PAGE &&
|
||||||
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE && mIns[sz - 3].mAddress == mIns[sz - 2].mAddress &&
|
mIns[sz - 2].mType == ASMIT_LDA && mIns[sz - 2].mMode == ASMIM_ZERO_PAGE && mIns[sz - 3].mAddress == mIns[sz - 2].mAddress &&
|
||||||
|
@ -5149,11 +5173,11 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
{
|
{
|
||||||
// check for usage of Y register
|
// check for usage of Y register
|
||||||
|
|
||||||
bool yother = false, yindex = false;
|
bool yother = false, yindex = false, xother = false, xindex = false;
|
||||||
int zreg = mIns[sz - 3].mAddress;
|
int zreg = mIns[sz - 3].mAddress;
|
||||||
int limit = mIns[sz - 1].mAddress;
|
int limit = mIns[sz - 1].mAddress;
|
||||||
|
|
||||||
for (int i = 0; i < sz - 4; i++)
|
for (int i = 0; i < sz - 3; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType == ASMIT_INY || mIns[i].mType == ASMIT_DEY || mIns[i].mType == ASMIT_TAY)
|
if (mIns[i].mType == ASMIT_INY || mIns[i].mType == ASMIT_DEY || mIns[i].mType == ASMIT_TAY)
|
||||||
yother = true;
|
yother = true;
|
||||||
|
@ -5164,10 +5188,24 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
else
|
else
|
||||||
yother = true;
|
yother = true;
|
||||||
}
|
}
|
||||||
else if (mIns[i].mType == ASMIT_LDX && mIns[i].mAddress == zreg)
|
|
||||||
yother = true;
|
|
||||||
else if (!yindex && (mIns[i].mType == ASMIT_STY || mIns[i].mType == ASMIT_TYA || mIns[i].mMode == ASMIM_ABSOLUTE_Y || mIns[i].mMode == ASMIM_INDIRECT_Y))
|
else if (!yindex && (mIns[i].mType == ASMIT_STY || mIns[i].mType == ASMIT_TYA || mIns[i].mMode == ASMIM_ABSOLUTE_Y || mIns[i].mMode == ASMIM_INDIRECT_Y))
|
||||||
yother = true;
|
yother = true;
|
||||||
|
else if (mIns[i].mType != ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
yother = true;
|
||||||
|
|
||||||
|
if (mIns[i].mType == ASMIT_INX || mIns[i].mType == ASMIT_DEX || mIns[i].mType == ASMIT_TAX)
|
||||||
|
xother = true;
|
||||||
|
else if (mIns[i].mType == ASMIT_LDX)
|
||||||
|
{
|
||||||
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
xindex = true;
|
||||||
|
else
|
||||||
|
xother = true;
|
||||||
|
}
|
||||||
|
else if (!xindex && (mIns[i].mType == ASMIT_STX || mIns[i].mType == ASMIT_TXA || mIns[i].mMode == ASMIM_ABSOLUTE_X || mIns[i].mMode == ASMIM_INDIRECT_X))
|
||||||
|
xother = true;
|
||||||
|
else if (mIns[i].mType != ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
xother = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!yother)
|
if (!yother)
|
||||||
|
@ -5176,10 +5214,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
for (int i = 0; i + 3 < sz; i++)
|
for (int i = 0; i + 3 < sz; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType != ASMIT_LDY)
|
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
lblock->mIns.Push(mIns[i]);
|
|
||||||
else if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
||||||
|
else if (mIns[i].mType != ASMIT_LDY)
|
||||||
|
lblock->mIns.Push(mIns[i]);
|
||||||
}
|
}
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_IMMEDIATE, limit));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_IMMEDIATE, limit));
|
||||||
|
@ -5192,12 +5230,43 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
eblock->mTrueJump = mFalseJump;
|
eblock->mTrueJump = mFalseJump;
|
||||||
eblock->mFalseJump = nullptr;
|
eblock->mFalseJump = nullptr;
|
||||||
|
|
||||||
|
|
||||||
mIns.Clear();
|
mIns.Clear();
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, zreg));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_ZERO_PAGE, zreg));
|
||||||
mBranch = ASMIT_JMP;
|
mBranch = ASMIT_JMP;
|
||||||
mTrueJump = lblock;
|
mTrueJump = lblock;
|
||||||
mFalseJump = nullptr;
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (!xother)
|
||||||
|
{
|
||||||
|
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
||||||
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
|
for (int i = 0; i + 3 < sz; i++)
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TXA, ASMIM_IMPLIED));
|
||||||
|
else if (mIns[i].mType != ASMIT_LDX)
|
||||||
|
lblock->mIns.Push(mIns[i]);
|
||||||
|
}
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INX, ASMIM_IMPLIED));
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPX, ASMIM_IMMEDIATE, limit));
|
||||||
|
lblock->mBranch = mBranch;
|
||||||
|
lblock->mTrueJump = lblock;
|
||||||
|
lblock->mFalseJump = eblock;
|
||||||
|
|
||||||
|
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, zreg));
|
||||||
|
eblock->mBranch = ASMIT_JMP;
|
||||||
|
eblock->mTrueJump = mFalseJump;
|
||||||
|
eblock->mFalseJump = nullptr;
|
||||||
|
|
||||||
|
mIns.Clear();
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_ZERO_PAGE, zreg));
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump = lblock;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5219,10 +5288,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
else
|
else
|
||||||
yother = true;
|
yother = true;
|
||||||
}
|
}
|
||||||
else if (mIns[i].mType == ASMIT_LDX && mIns[i].mAddress == zreg)
|
|
||||||
yother = true;
|
|
||||||
else if (!yindex && (mIns[i].mType == ASMIT_STY || mIns[i].mType == ASMIT_TYA || mIns[i].mMode == ASMIM_ABSOLUTE_Y || mIns[i].mMode == ASMIM_INDIRECT_Y))
|
else if (!yindex && (mIns[i].mType == ASMIT_STY || mIns[i].mType == ASMIT_TYA || mIns[i].mMode == ASMIM_ABSOLUTE_Y || mIns[i].mMode == ASMIM_INDIRECT_Y))
|
||||||
yother = true;
|
yother = true;
|
||||||
|
else if (mIns[i].mType != ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
yother = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!yother)
|
if (!yother)
|
||||||
|
@ -5231,10 +5300,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
for (int i = 0; i + 1 < sz; i++)
|
for (int i = 0; i + 1 < sz; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType != ASMIT_LDY)
|
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
lblock->mIns.Push(mIns[i]);
|
|
||||||
else if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
||||||
|
else if (mIns[i].mType != ASMIT_LDY)
|
||||||
|
lblock->mIns.Push(mIns[i]);
|
||||||
}
|
}
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
|
||||||
lblock->mBranch = mBranch;
|
lblock->mBranch = mBranch;
|
||||||
|
@ -5262,14 +5331,15 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
{
|
{
|
||||||
// check for usage of Y register
|
// check for usage of Y register
|
||||||
|
|
||||||
bool yother = false, yindex = false, lchanged = false;
|
bool yother = false, yindex = false, lchanged = false, xother = false, xindex = false;
|
||||||
int lreg = mIns[sz - 1].mAddress;
|
int lreg = mIns[sz - 1].mAddress;
|
||||||
int zreg = mIns[sz - 3].mAddress;
|
int zreg = mIns[sz - 3].mAddress;
|
||||||
|
|
||||||
for (int i = 0; i < sz - 4; i++)
|
for (int i = 0; i < sz - 3; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].ChangesAddress())
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == lreg && mIns[i].ChangesAddress())
|
||||||
lchanged = true;
|
lchanged = true;
|
||||||
|
|
||||||
if (mIns[i].mType == ASMIT_INY || mIns[i].mType == ASMIT_DEY || mIns[i].mType == ASMIT_TAY)
|
if (mIns[i].mType == ASMIT_INY || mIns[i].mType == ASMIT_DEY || mIns[i].mType == ASMIT_TAY)
|
||||||
yother = true;
|
yother = true;
|
||||||
else if (mIns[i].mType == ASMIT_LDY)
|
else if (mIns[i].mType == ASMIT_LDY)
|
||||||
|
@ -5279,10 +5349,26 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
else
|
else
|
||||||
yother = true;
|
yother = true;
|
||||||
}
|
}
|
||||||
else if (mIns[i].mType == ASMIT_LDX && mIns[i].mAddress == zreg)
|
|
||||||
yother = true;
|
|
||||||
else if (!yindex && (mIns[i].mType == ASMIT_STY || mIns[i].mType == ASMIT_TYA || mIns[i].mMode == ASMIM_ABSOLUTE_Y || mIns[i].mMode == ASMIM_INDIRECT_Y))
|
else if (!yindex && (mIns[i].mType == ASMIT_STY || mIns[i].mType == ASMIT_TYA || mIns[i].mMode == ASMIM_ABSOLUTE_Y || mIns[i].mMode == ASMIM_INDIRECT_Y))
|
||||||
yother = true;
|
yother = true;
|
||||||
|
else if (mIns[i].mType != ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
yother = true;
|
||||||
|
|
||||||
|
if (mIns[i].mType == ASMIT_INX || mIns[i].mType == ASMIT_DEX || mIns[i].mType == ASMIT_TAX)
|
||||||
|
xother = true;
|
||||||
|
else if (mIns[i].mType == ASMIT_LDX)
|
||||||
|
{
|
||||||
|
if (mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
xindex = true;
|
||||||
|
else
|
||||||
|
xother = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
xother = true;
|
||||||
|
else if (!xindex && (mIns[i].mType == ASMIT_STX || mIns[i].mType == ASMIT_TXA || mIns[i].mMode == ASMIM_ABSOLUTE_X || mIns[i].mMode == ASMIM_INDIRECT_X))
|
||||||
|
xother = true;
|
||||||
|
else if (mIns[i].mType != ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
xother = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!yother && !lchanged)
|
if (!yother && !lchanged)
|
||||||
|
@ -5291,10 +5377,10 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
for (int i = 0; i + 3 < sz; i++)
|
for (int i = 0; i + 3 < sz; i++)
|
||||||
{
|
{
|
||||||
if (mIns[i].mType != ASMIT_LDY)
|
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
lblock->mIns.Push(mIns[i]);
|
|
||||||
else if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TYA, ASMIM_IMPLIED));
|
||||||
|
else if (mIns[i].mType != ASMIT_LDY)
|
||||||
|
lblock->mIns.Push(mIns[i]);
|
||||||
}
|
}
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
|
||||||
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_ZERO_PAGE, lreg));
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPY, ASMIM_ZERO_PAGE, lreg));
|
||||||
|
@ -5315,8 +5401,38 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoop(NativeCodeProcedure * proc)
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
else if (!xother && !lchanged)
|
||||||
|
{
|
||||||
|
NativeCodeBasicBlock* lblock = proc->AllocateBlock();
|
||||||
|
NativeCodeBasicBlock* eblock = proc->AllocateBlock();
|
||||||
|
for (int i = 0; i + 3 < sz; i++)
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == zreg)
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_TXA, ASMIM_IMPLIED));
|
||||||
|
else if (mIns[i].mType != ASMIT_LDX)
|
||||||
|
lblock->mIns.Push(mIns[i]);
|
||||||
}
|
}
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_INX, ASMIM_IMPLIED));
|
||||||
|
lblock->mIns.Push(NativeCodeInstruction(ASMIT_CPX, ASMIM_ZERO_PAGE, lreg));
|
||||||
|
lblock->mBranch = mBranch;
|
||||||
|
lblock->mTrueJump = lblock;
|
||||||
|
lblock->mFalseJump = eblock;
|
||||||
|
|
||||||
|
eblock->mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, zreg));
|
||||||
|
eblock->mBranch = ASMIT_JMP;
|
||||||
|
eblock->mTrueJump = mFalseJump;
|
||||||
|
eblock->mFalseJump = nullptr;
|
||||||
|
|
||||||
|
mIns.Clear();
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_ZERO_PAGE, zreg));
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
mTrueJump = lblock;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTrueJump && mTrueJump->OptimizeSimpleLoop(proc))
|
if (mTrueJump && mTrueJump->OptimizeSimpleLoop(proc))
|
||||||
|
@ -5351,6 +5467,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
// shorten x/y register livetime
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
for (int i = 0; i + 1 < mIns.Size(); i++)
|
||||||
|
{
|
||||||
|
if (mIns[i].mType == ASMIT_LDY && mIns[i].mMode == ASMIM_IMMEDIATE)
|
||||||
|
{
|
||||||
|
if (!mIns[i + 1].RequiresYReg() && !mIns[i + 1].ChangesYReg() && !(mIns[i + 1].mLive & LIVE_CPU_REG_Z))
|
||||||
|
{
|
||||||
|
NativeCodeInstruction ins = mIns[i];
|
||||||
|
mIns[i] = mIns[i + 1];
|
||||||
|
mIns[i + 1] = ins;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool progress = false;
|
bool progress = false;
|
||||||
do {
|
do {
|
||||||
|
@ -5428,16 +5560,49 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
{
|
{
|
||||||
mIns[i].mAddress &= mIns[i + 1].mAddress;
|
mIns[i].mAddress &= mIns[i + 1].mAddress;
|
||||||
mIns[i + 1].mType = ASMIT_NOP;
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (mIns[i].mType == ASMIT_ORA && mIns[i + 1].mType == ASMIT_ORA && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mMode == ASMIM_IMMEDIATE)
|
else if (mIns[i].mType == ASMIT_ORA && mIns[i + 1].mType == ASMIT_ORA && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
mIns[i].mAddress |= mIns[i + 1].mAddress;
|
mIns[i].mAddress |= mIns[i + 1].mAddress;
|
||||||
mIns[i + 1].mType = ASMIT_NOP;
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (mIns[i].mType == ASMIT_EOR && mIns[i + 1].mType == ASMIT_EOR && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mMode == ASMIM_IMMEDIATE)
|
else if (mIns[i].mType == ASMIT_EOR && mIns[i + 1].mType == ASMIT_EOR && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
mIns[i].mAddress ^= mIns[i + 1].mAddress;
|
mIns[i].mAddress ^= mIns[i + 1].mAddress;
|
||||||
mIns[i + 1].mType = ASMIT_NOP;
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_ORA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0)
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_EOR && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0)
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_LDA && mIns[i + 1].mType == ASMIT_AND && mIns[i + 1].mMode == ASMIM_IMMEDIATE && mIns[i + 1].mAddress == 0xff)
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mType == ASMIT_CLC && mIns[i + 1].mType == ASMIT_ROR)
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = ASMIT_NOP;
|
||||||
|
mIns[i + 1].mType = ASMIT_LSR;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress &&
|
||||||
|
(mIns[i + 1].mType == ASMIT_LSR || mIns[i + 1].mType == ASMIT_ASL || mIns[i + 1].mType == ASMIT_ROL || mIns[i + 1].mType == ASMIT_ROR))
|
||||||
|
{
|
||||||
|
mIns[i + 0].mType = mIns[i + 1].mType;
|
||||||
|
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 1].mType = ASMIT_STA;
|
||||||
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & LIVE_CPU_REG_A) &&
|
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 1].mLive & LIVE_CPU_REG_A) &&
|
||||||
|
@ -5446,6 +5611,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
{
|
{
|
||||||
mIns[i + 1].mType = ASMIT_NOP;
|
mIns[i + 1].mType = ASMIT_NOP;
|
||||||
mIns[i + 0].mLive |= LIVE_CPU_REG_Z;
|
mIns[i + 0].mLive |= LIVE_CPU_REG_Z;
|
||||||
|
progress = true;
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
mIns[i + 1].mType == ASMIT_ASL && mIns[i + 1].mMode == ASMIM_ZERO_PAGE &&
|
||||||
|
@ -5455,11 +5621,12 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i + 0].mType = ASMIT_ASL;
|
mIns[i + 0].mType = ASMIT_ASL;
|
||||||
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
mIns[i + 0].mMode = ASMIM_IMPLIED;
|
||||||
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
mIns[i + 0].mLive |= LIVE_CPU_REG_A;
|
||||||
|
progress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 &&
|
||||||
mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 1].mLive & (LIVE_MEM | LIVE_CPU_REG_Y)))
|
mIns[i + 1].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 1].mLive & LIVE_MEM ))
|
||||||
{
|
{
|
||||||
int apos, breg, ireg;
|
int apos, breg, ireg;
|
||||||
if (FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg))
|
if (FindAddressSumY(i, mIns[i + 1].mAddress, apos, breg, ireg))
|
||||||
|
@ -5471,6 +5638,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[apos + 6].mType = ASMIT_NOP;
|
mIns[apos + 6].mType = ASMIT_NOP;
|
||||||
mIns[apos + 6].mMode = ASMIM_IMPLIED;
|
mIns[apos + 6].mMode = ASMIM_IMPLIED;
|
||||||
}
|
}
|
||||||
|
if (mIns[i + 1].mLive & LIVE_CPU_REG_Y)
|
||||||
|
{
|
||||||
|
mIns.Insert(i + 2, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns[i + 2].mLive |= LIVE_CPU_REG_Y;
|
||||||
|
}
|
||||||
mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
|
mIns[i + 0].mMode = ASMIM_ZERO_PAGE;
|
||||||
mIns[i + 0].mAddress = ireg;
|
mIns[i + 0].mAddress = ireg;
|
||||||
mIns[i + 1].mAddress = breg;
|
mIns[i + 1].mAddress = breg;
|
||||||
|
@ -5546,6 +5718,15 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i + 2].mType = ASMIT_SBC; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 1;
|
mIns[i + 2].mType = ASMIT_SBC; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 1;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (
|
||||||
|
mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 &&
|
||||||
|
mIns[i + 1].mType == ASMIT_CMP && mIns[i + 1].mMode == ASMIM_IMMEDIATE &&
|
||||||
|
mIns[i + 2].mType == ASMIT_ROR && mIns[i + 2].mMode == ASMIM_IMPLIED)
|
||||||
|
{
|
||||||
|
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||||
|
mIns[i + 2].mType = ASMIT_CLC; mIns[i + 2].mMode = ASMIM_IMPLIED;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
#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 &&
|
||||||
|
|
|
@ -57,6 +57,8 @@ public:
|
||||||
bool ChangesAddress(void) const;
|
bool ChangesAddress(void) const;
|
||||||
bool ChangesAccu(void) const;
|
bool ChangesAccu(void) const;
|
||||||
bool RequiresAccu(void) const;
|
bool RequiresAccu(void) const;
|
||||||
|
bool RequiresYReg(void) const;
|
||||||
|
bool ChangesYReg(void) const;
|
||||||
bool SameEffectiveAddress(const NativeCodeInstruction& ins) const;
|
bool SameEffectiveAddress(const NativeCodeInstruction& ins) const;
|
||||||
bool IsSame(const NativeCodeInstruction& ins) const;
|
bool IsSame(const NativeCodeInstruction& ins) const;
|
||||||
bool IsCommutative(void) const;
|
bool IsCommutative(void) const;
|
||||||
|
|
|
@ -34,7 +34,7 @@ bool SourceFile::ReadLine(char* line)
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceFile::SourceFile(void)
|
SourceFile::SourceFile(void)
|
||||||
: mFile(nullptr), mFileName{ 0 }
|
: mFile(nullptr), mFileName{ 0 }, mStack(nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,40 @@ void SourceFile::Close(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SourceFile::PushSource(void)
|
||||||
|
{
|
||||||
|
SourceStack* stack = new SourceStack();
|
||||||
|
stack->mUp = mStack;
|
||||||
|
mStack = stack;
|
||||||
|
stack->mFilePos = ftell(mFile);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SourceFile::PopSource(void)
|
||||||
|
{
|
||||||
|
SourceStack* stack = mStack;
|
||||||
|
if (stack)
|
||||||
|
{
|
||||||
|
fseek(mFile, stack->mFilePos, SEEK_SET);
|
||||||
|
mStack = mStack->mUp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SourceFile::DropSource(void)
|
||||||
|
{
|
||||||
|
SourceStack* stack = mStack;
|
||||||
|
if (stack)
|
||||||
|
{
|
||||||
|
mStack = mStack->mUp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Preprocessor::NextLine(void)
|
bool Preprocessor::NextLine(void)
|
||||||
{
|
{
|
||||||
int s = 0;
|
int s = 0;
|
||||||
|
@ -171,6 +205,21 @@ bool Preprocessor::CloseSource(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Preprocessor::PushSource(void)
|
||||||
|
{
|
||||||
|
return mSource->PushSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Preprocessor::PopSource(void)
|
||||||
|
{
|
||||||
|
return mSource->PopSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Preprocessor::DropSource(void)
|
||||||
|
{
|
||||||
|
return mSource->DropSource();
|
||||||
|
}
|
||||||
|
|
||||||
Preprocessor::Preprocessor(Errors* errors)
|
Preprocessor::Preprocessor(Errors* errors)
|
||||||
: mSource(nullptr), mSourceList(nullptr), mPaths(nullptr), mErrors(errors)
|
: mSource(nullptr), mSourceList(nullptr), mPaths(nullptr), mErrors(errors)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,15 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "MachineTypes.h"
|
#include "MachineTypes.h"
|
||||||
|
|
||||||
|
class SourceStack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SourceStack* mUp;
|
||||||
|
|
||||||
|
int mFilePos;
|
||||||
|
Location mLocation;
|
||||||
|
};
|
||||||
|
|
||||||
class SourceFile
|
class SourceFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -11,6 +20,7 @@ public:
|
||||||
|
|
||||||
SourceFile * mUp, * mNext;
|
SourceFile * mUp, * mNext;
|
||||||
Location mLocation;
|
Location mLocation;
|
||||||
|
SourceStack * mStack;
|
||||||
|
|
||||||
bool ReadLine(char* line);
|
bool ReadLine(char* line);
|
||||||
|
|
||||||
|
@ -19,6 +29,11 @@ public:
|
||||||
|
|
||||||
bool Open(const char* name, const char * path);
|
bool Open(const char* name, const char * path);
|
||||||
void Close(void);
|
void Close(void);
|
||||||
|
|
||||||
|
bool PushSource(void);
|
||||||
|
bool PopSource(void);
|
||||||
|
bool DropSource(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FILE* mFile;
|
FILE* mFile;
|
||||||
};
|
};
|
||||||
|
@ -51,6 +66,10 @@ public:
|
||||||
bool OpenSource(const char* reason, const char* name, bool local);
|
bool OpenSource(const char* reason, const char* name, bool local);
|
||||||
bool CloseSource(void);
|
bool CloseSource(void);
|
||||||
|
|
||||||
|
bool PushSource(void);
|
||||||
|
bool PopSource(void);
|
||||||
|
bool DropSource(void);
|
||||||
|
|
||||||
Preprocessor(Errors * errors);
|
Preprocessor(Errors * errors);
|
||||||
~Preprocessor(void);
|
~Preprocessor(void);
|
||||||
};
|
};
|
||||||
|
|
|
@ -121,7 +121,11 @@ const char* TokenNames[] = {
|
||||||
"'#endif'",
|
"'#endif'",
|
||||||
"'#ifdef'",
|
"'#ifdef'",
|
||||||
"'#ifndef'",
|
"'#ifndef'",
|
||||||
"'#pragma'"
|
"'#pragma'",
|
||||||
|
|
||||||
|
"'#assign'",
|
||||||
|
"'#repeat'",
|
||||||
|
"'#until'"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -529,6 +533,54 @@ void Scanner::NextToken(void)
|
||||||
if (mToken != TK_EOL)
|
if (mToken != TK_EOL)
|
||||||
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "End of line expected");
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "End of line expected");
|
||||||
}
|
}
|
||||||
|
else if (mToken == TK_PREP_ASSIGN)
|
||||||
|
{
|
||||||
|
mPreprocessorMode = true;
|
||||||
|
NextRawToken();
|
||||||
|
if (mToken == TK_IDENT)
|
||||||
|
{
|
||||||
|
const Ident* ident = mTokenIdent;
|
||||||
|
|
||||||
|
NextToken();
|
||||||
|
|
||||||
|
int v = PrepParseConditional();
|
||||||
|
Macro* macro = mDefines->Lookup(ident);
|
||||||
|
if (!macro)
|
||||||
|
{
|
||||||
|
macro = new Macro(ident);
|
||||||
|
mDefines->Insert(macro);
|
||||||
|
}
|
||||||
|
char buffer[20];
|
||||||
|
sprintf_s(buffer, "%d", v);
|
||||||
|
macro->SetString(buffer);
|
||||||
|
mPreprocessorMode = false;
|
||||||
|
if (mToken != TK_EOL)
|
||||||
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "End of line expected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mToken == TK_PREP_REPEAT)
|
||||||
|
{
|
||||||
|
mPreprocessor->PushSource();
|
||||||
|
}
|
||||||
|
else if (mToken == TK_PREP_UNTIL)
|
||||||
|
{
|
||||||
|
mPreprocessorMode = true;
|
||||||
|
NextToken();
|
||||||
|
int v = PrepParseConditional();
|
||||||
|
if (mToken != TK_EOL)
|
||||||
|
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "End of line expected");
|
||||||
|
|
||||||
|
if (v)
|
||||||
|
mPreprocessor->DropSource();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPreprocessor->PopSource();
|
||||||
|
mPreprocessor->PushSource();
|
||||||
|
mPreprocessor->NextLine();
|
||||||
|
mOffset = 0;
|
||||||
|
}
|
||||||
|
mPreprocessorMode = false;
|
||||||
|
}
|
||||||
else if (mToken == TK_IDENT)
|
else if (mToken == TK_IDENT)
|
||||||
{
|
{
|
||||||
Macro* def = nullptr;
|
Macro* def = nullptr;
|
||||||
|
@ -917,7 +969,7 @@ void Scanner::NextRawToken(void)
|
||||||
|
|
||||||
case '#':
|
case '#':
|
||||||
{
|
{
|
||||||
if (!mAssemblerMode)
|
if (!mAssemblerMode || mOffset == 1)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
char tkprep[128];
|
char tkprep[128];
|
||||||
|
@ -946,6 +998,12 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_PREP_ENDIF;
|
mToken = TK_PREP_ENDIF;
|
||||||
else if (!strcmp(tkprep, "pragma"))
|
else if (!strcmp(tkprep, "pragma"))
|
||||||
mToken = TK_PREP_PRAGMA;
|
mToken = TK_PREP_PRAGMA;
|
||||||
|
else if (!strcmp(tkprep, "assign"))
|
||||||
|
mToken = TK_PREP_ASSIGN;
|
||||||
|
else if (!strcmp(tkprep, "repeat"))
|
||||||
|
mToken = TK_PREP_REPEAT;
|
||||||
|
else if (!strcmp(tkprep, "until"))
|
||||||
|
mToken = TK_PREP_UNTIL;
|
||||||
else
|
else
|
||||||
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", tkprep);
|
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid preprocessor command", tkprep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,10 @@ enum Token
|
||||||
TK_PREP_IFNDEF,
|
TK_PREP_IFNDEF,
|
||||||
TK_PREP_PRAGMA,
|
TK_PREP_PRAGMA,
|
||||||
|
|
||||||
|
TK_PREP_ASSIGN,
|
||||||
|
TK_PREP_REPEAT,
|
||||||
|
TK_PREP_UNTIL,
|
||||||
|
|
||||||
NUM_TOKENS
|
NUM_TOKENS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue